Quantcast
Channel: SCN : Blog List - ABAP Development
Viewing all 943 articles
Browse latest View live

Adobeform for multiple trays

$
0
0

Adobeform for multiple trays

 

We have some printers with multiple trays. Depending on the message category, we can print adobeform from a specific tray. Rule will be always as simple i.e. for one message category; we know the tray number where we want to print the adobeform.

 

First we need, maintain data in TVARVC as below:

 

Go to Transaction STVARV and maintain the data for the Message Category and Tray Value.

 

 

1.jpg

Name contains the Message Category and the Value is Tray Name / Number (i.e. either for Duplex Printer or Simplex Printer)

 

Before calling the function module ‘FP_JOB_OPEN’, pass the value of the tray name or number in the field ‘JOB_PROFILE’ of the structure ‘SFPOUTPUTPARAMS’ i.e. form processing output parameter.

 

Code as below:

Taking example for Production Order (CO01/02/03)

 

Transaction OPK8

List Name

 

3.jpg

 

Driver Program: PSFC_OBJECT_LIST_PDF

Enhancement Spot at Form ‘FILL_OUTPUTPARAMS’.

 

2.jpg

DATA:        lv_messageo TYPE fpjobprofile,

                  lv_msgo     TYPE rvari_vnam.

 

CONSTANTS: lc_msg1 TYPE rvari_vnam VALUE 'ZFPP01_',

                     lc_msg2 TYPE rvari_vnam VALUE 'ZFPP02_'.

 

*-- Concatenate like 'ZFPP01_LG01ZP01'

*-- print_co-lstid contains value of list name i.e. LG01 and print_co-auart contains the value of Order Type i.e. ‘ZP01’, ‘ZP03’, etc.

CONCATENATE lc_msg1 print_co-lstid print_co-auart INTO lv_msgo.

 

*-- Select query to fetch the tray value from table 'TVARVC' comparing the Message Category

 

SELECT SINGLE low  "ABAP/4: Selection value (LOW)

INTO lv_messageo

FROM tvarvc "Table of Variant Variables (Client

WHERE name = lv_msgo

      AND type = lc_value_p.

IF sy-subrc EQ 0.

    xs_outputparams-job_profile = lv_messageo. " Populate the value of the Tray name in the field 'JOB_PROFILE'.

ENDIF.

 

This is how depending on the message category, print will come from a specific tray in the printer has multiple trays.

 

Thanks for reading the document.

 

Regards,

Debopriya Ghosh


Enhance "GO TO" Menu in BP(Business Partner) using BDT(Business Data Toolset)

$
0
0

Business Data Toolset is a easy way to enhance different SAP Business Objects.

According to SAP Help:http://help.sap.com/saphelp_crm50/helpdata/en/2f/696d360856e808e10000009b38f839/frameset.htm

All menu options not fixed in the menu can be included in this menu through additional functions. These additional functions can be reached through the following submenus:

·         Further object functions (<Object> menu)

·         Further editing (editing menu)

·         Additional goto destinations (Goto menu)

·         Additional extras (Extras menu)

In this article is an example of  "Go To" menu enhancement on SAP Business Partner.

1.     Run transaction BUPT

2.     Then go to Menu: Business partner -> Control -> GUI Functions - > Additional Functions (transaction code BUS9)

1.jpg

3. In the open transaction  create new Menu Item:

a)      a. Menu item description;

b)      b. Menu to Enhance;

c)      c. Mode, in which the function is available

2.jpg

If we leave “Application” empty, new function will be available from all Business partner lists.

a)      d. View  in which the new function is  available, empty – available everywhere

3.png

e.  e. The same as step D.

4.png

Now new function is available fron Menu “GoTo ->  More GoTo Targets”.

5.jpg

But we still need to assign functionality to the new menu item

To do this, perform following steps:

1.      1.  In transaction BUPT, go to Menu: Business partner -> Control -> Events ->Business Data Toolset (BUS7)

6.jpg

1.       2. Choose “FCODE     Separate Function Code”

2.       3. Copy any of the functions   to your own function.  As example I’ve copied function BUP_BUPA_EVENT_FCODE to the function ZCBP_BUPA_EVENT_FCODE_DOKBS.  And  have written such code. Parameter “I_FCODE” will contain menu name which we have created  earlier.

7.jpg

8.jpg

1.      4. Then we need to fill customizing table from step 3;

9.jpg

1.      6. Then we need to fill customizing table from step 3

10.png

11.jpg

Everything works. In my task, from BP other system must be launched ,

 

By means  of Business data toolset you can extend objects with customer screens, logic and check. All information you can find at - http://help.sap.com/saphelp_crm50/helpdata/en/2f/696d360856e808e10000009b38f839/frameset.htm.

 

I hope this information will be useful.

Best regards.

Pavel Rumyantsev

Auto generating UML diagrams from ABAP code

$
0
0

Alternative title - I hate doco

 

http://www.wombling.com/wp-content/uploads/2013/08/run-from-doco-624x282.png

It’s kinda a mantra that I live a reasonable part of my life to. I think the above image is a not unjustifiable representation of my feelings about documentation:

But there are many good reasons that I should be doing doco. Most of them are supposed to save the customer money in the long run. And occasionally by doing the doco, I even find some small errors in my code that I hadn’t seen before.

InnoJam Sydney 2011

Before InnoJam had any of that fun fluffy design thinking aspect to it, we ran one in Sydney. It was good fun, and people could build whatever the heck they wanted.

In staying true to my aversion for writing doco, I came up with an idea about auto-generation UML diagrams from SAP code.

Here’s a video of the solution we came up with:

 

here’s a link to the Prezi that I presented in that video:

http://prezi.com/zri5q-ib4vzp/?utm_campaign=share&utm_medium=copy&rc=ex0share

 

 

 

 

 

I wrote a blog post about it:

"Programmers are lazy" - InnoJam them!

But it was long time ago and the move to a new version of SCN has kinda buggered it up.

Anyway, in short – Rui Nogueira never managed to get the terms and conditions of CodeExchange changed to a level where I’m happy to support it and put code in there. I’m pretty sure he tried though. So I didn’t do anything with the code.

 

Fast forward 3 years

I have a whiteboard in the office covered in post-it notes. They all represent at least one development that I’ve done for the current project I’m working on. At the beginning of the project, I was very good, and did all my doco as I went along. Then the poo hit the fan, and everyone wanted everything done yesterday, and didn’t care about doco.

So I now have a whiteboard full of post-it notes that represent potentially weeks of doco hell for me. So in my “free time” in the evening I decided to see if I could recreate the solution that we’d built in Sydney, and perhaps make it a little nicer.

 

UML output

The first thing I decided, was that I was NOT going to try to build the graphical output myself. Having had lots of fun in Sydney trying to make Gravity do something it really wasn’t designed for I thought I’d research how else I could get my interaction diagrams created.

If in doubt Wikipedia

http://en.wikipedia.org/wiki/List_of_UML_tools

There were loads there, and I’d pretty much decided on UMLet when I discovered something about interaction diagrams. Basically, interaction diagrams are supposed to show interaction between objects. Bit bloody obvious really. However, the thing is, if I’m documenting my code, I’d really like to show the interaction within my objects too. I.e. if I make a call to a private method of my class, I’d really like that to show up in my diagram. Given that interaction diagrams are only supposed to show external interaction it’s not surprising that most of the tools for creating the diagrams don’t really support this idea of internal object calls.

So a bit of browsing later and I found PlantUML. It has some awesome functionality for creating sequence diagrams, actually, most UML diagrams it seems, but it was the sequence diagrams that I was interested in.

Here’s a simple example:

http://www.wombling.com/wp-content/uploads/2013/08/simple_example.png

 

See how it’s quite possible to show “internal” calls of an instance and also show the life time of those calls. This feature I didn’t find on the other free UML tools that I looked at. There are a bunch of other formatting features that can be used too. If you’re interested check out their website: http://plantuml.sourceforge.net/sequence.html

 

Intercepting the SAP standard UML generation

So in transaction SAT there is the possibility to generate your own JNet UML sequence diagram (this exists as standard.)

http://www.wombling.com/wp-content/uploads/2013/08/press-the-button.png

 

However, it does not allow you to do things like filter out standard SAP routines (as far as I know! If anyone can tell me how to do this (without needing to list every method I call, please let me know!) When I was looking at one of my examples, where I ran a program to generate a performance review document for an employee, there were over 100,000 different routines called. Only about 400 of those calls involved my code, so you can imagine generating a UML diagram for the whole 100,000 calls would be a bit of overkill (not to mention an impossible to read diagram).

In customer systems there is a function module  ATRA_UML_DECIDER  that has been purposely handicapped. One does have to wonder why this has been done, but nevertheless it has.  It allows the user to chose from a list of potential UML extraction routines. All of these routines implement the IF_ATRA_UML_TOOL interface. There are classes for extracting to JNet, Borland Together and Altova. Now, I’m sure that Borland and Altova have good products, it’s just that I don’t really want to spend money on then when there are perfectly good (for my tasks) free and open source products out there.

There is a factory class/method CL_ATRA_UML_FACTORY  that creates an instance of a class implementing the interface. I overrode this method to use my particular extractor if it was me running the code. In the future, I might enhance this to check for a user role, or perhaps a user parameter, that’s trivial, the main point will be to allow others to access this logic too.

The guts of the code

Simply my implementation of the interface reads the table of data that is passed to the interface, removes all calls that aren’t to or from custom code and then builds a PlantUML representation of that code.

Here’s a very simple output that generates the diagram above.

@startuml
hide footbox
autonumber
participant "Instance 1 of Class\nZCL_HR_EMPLOYEE" as 1
1 -> 1: Call method GET_HELD_QUALIFICATIONS
activate 1
1 -> 1: Call method ZCL_HR_OBJECT->GET_RELATIONSHIPS
activate 1
create "Static Methods of Class\nCL_HRBAS_READ_INFOTYPE" as 2
1 -> 2: Call method GET_INSTANCE
activate 2
2 --> 1
deactivate 2
create "Instance 1 of Class\nCL_HRBAS_READ_INFOTYPE" as 3
1 -> 3: Call method IF_HRBAS_READ_INFOTYPE~READ_PLAIN_1001
activate 3
3 --> 1
deactivate 3
1 --> 1
deactivate 1
create "Instance 1 of Class\nZCL_HR_QUALIFICATION" as 4
1 -> 4: Create instance of class ZCL_HR_QUALIFICATION
activate 4
4 -> 4: Call method ZCL_HR_OBJECT->CONSTRUCTOR
activate 4
create "Function Group\nRHS0" as 5
4 -> 5: Call FM RH_GET_ACTIVE_WF_PLVAR
activate 5
5 --> 4
deactivate 5
4 --> 4
deactivate 4
4 --> 1
deactivate 4
deactivate 1
@enduml

 

A slightly less trivial example

The following code does some pretty simple stuff, it finds who is my manager, and finds out what required qualifications my position/job has.

DATA: lo_emp TYPE REF TO zcl_hr_employee,
lt_managers TYPE ztthr_employee_objects,
lt_required_quals TYPE ztthr_qualifications.
TRY.
lo_emp = zcl_hr_employee=>get_employee_by_user_id( sy-uname ).
lt_managers = lo_emp->get_position( )->get_managers_recursive( ).
lt_required_quals = lo_emp->get_position( )->get_required_qualifications( ).
CATCH zcx_hr_no_managing_pos_found  ” No managing position found
zcx_hr_no_holders_found  ” no holders for position found.
zcx_hr_no_position_found    ” no position found
zcx_hr_user_id_not_found.  ” cannot find user id for employee
ENDTRY.

 

So I thought I’d trace it:

it works out at around 200,000 different routines being called. 62 of those are my code, the rest standard.

http://www.wombling.com/wp-content/uploads/2013/08/run-through-1.png

First of all, I need to schedule a trace for myself…

run through 2

 

run through 3

 

Need to know which session I will be recording. If I left it as “Any” it will start recording this session, not very useful!

run through 4

 

Session 2 it is!

run through 5

run through 6

actually run it now!

and the schedule status changes to executed.

run through 7

 

I now need to delete the scheduled measurement. Despite the intimidating words, this does not delete my measurement, just the scheduling of it.

run through 8

 

now swapping to the “Evaluate” tab in SAT I can see my measurement, and I can click to output to UML

run through 9

 

Late breaking discovery! - Filter data using SLAD!

In a somewhat surprising discovery, I found that I can filter the results of the trace so that only the custom code bits get processed in UML handling routines. This speeds up the processing immensely. HOWEVER! This does mean that you will NOT see where your code calls the SAP standard code, but for some diagramming tasks this would be fine.

slad filter1.png

 

slad filter2.png

Clicking on the button triggers a bit of a pause whilst the system code chugs away and does loads of stuff it doesn’t need to do…

Then

run through 10

Save the data and PlantUML starts converting it immediately:

run through 11

and the result:

example

Would probably have been a little bigger if my employee had a job assigned to their position, but you can see how incredibly easy this now makes documenting the functionality I’ve built.

After checking the SCN T&C and finding similar (if not worse conditions for the upload of SAP derivative code (it uses an SAP standard interface, so it probably is)) and the same indemnity clauses that make me refuse to participate in Code Exchange, I've decided not to share the code here. That said if someone else is willing to put the code out there on Code Exchange I'm more than happy to provide it to them. Perhaps someone will put their hand up to load it into Code Exchange - Gregor Wolf ???


This content was previously published on my own blog, but the tip about the SLAD filter wasn't, and certainly the code wasn't published there. Some excellent points have been raised about how this isn't a replacement for actually documenting the functionality of the code that has been built. But, I have found at least one case where using this tooling has helped me write a better bit of code by sharing references to objects that I didn't realise were being instantiated multiple times. Could something like this help you with your doco? Do you have any thoughts?

Sending SMS to mobile phones (in the Netherlands)

$
0
0

I recently got a question about sending SMS text messages from SAP to a mobile phone. My first thoughts went to specialized hardware, but I found out there is a much simpler way to achieve this.

 

I don't know if this solution is available in the rest of the world, but here in the Netherlands we have a specialized public gateway for this !

You can activate this gateway by sending a code ("EMAIL AAN") to your network number:

 

Network number     Provider (site)

321                       www.hi.nl

969                       www.kpn.com

126                       www.orange.nl

888                       www.t-mobile.nl

221                       www.telfort.nl

125                       www.vodafone.nl

 

After you send this SMS, you receive a message back that the gateway has been activated and it also contains an email adddress (probably something like +316XXXXXXXX@GIN.NL).

 

From this point on, you can send an email from SAP to this address and the telephone will receive the sender and the subject of this email as an SMS text message ! There is ofcourse always the size limit of 160 characters.

 

Sending an SMS to your network with code "EMAIL UIT" will switch the gateway off.

 

There are probably costs for using this gateway, but I don't know what they are.

 

Furthermore I should say that I only tested it with the Vodafone network, but I am confident that this should work on other networks too. Maybe the on/off codes differ a little bit.

 

A nice way to send SMS messages without much hassle.

The issue with having many small classes

$
0
0

Aftermath

The previous blog post was about applying design principles to the architecture of a simple parser application, which served as an exercise application. It led to quite a few, small classes in the end which all had their own responsibility.

Big Picture.PNG

Issue

As most of the classes deal with solving a certain aspect of the exercise, one class has the responsibility to arrange the work of the other classes to solve what needs to be solved. This class implements the interface ZIF_OCR_PARSING_ALGORITHM . An instance of that class is given to every consumer which needs to parse some sample input.
Every low level class that this class is dealing with to “orchestrate” the program flow, is registered as an dependency. Dependencies can be declared in the constructor of this course grained class. This makes creation of that class impossible without satisfying its dependencies.

methods CONSTRUCTOR
importing
!IO_FILE_ACCESS type ref to ZIF_OCR_FILE_ACCESS
!IO_LINES_SEPERATOR type ref to ZIF_OCR_LINES_SEPERATOR
!IO_CHARACTERS_SEPERATOR type ref to ZIF_OCR_CHARACTERS_SEPERATOR
!IO_CHARACTER_PARSER type ref to ZIF_OCR_CHARACTER_PARSER .

 

Providing dependencies during object creation by an external caller is called “dependency injection” (DI) as opposed to having classes that create their dependencies on their own. As the creation of the low level instances is not in the control of the class that orchestrates the parser flow, this paradigm is also called “Inversion of control” (IoC).
However, this approach has another challenge ready. That issue has been described very clearly by Oliver as a reply to the previous blog post
“Injection in the constructor – even to an interface – looks like quite tight coupling to me as it leaves the consumer of the coarse-grained class (the algorithm, in your case) to instantiate the composites.”

Factory

Of course the consumer of the composite object model should not create it on its own. One possibility would be to utilize the factory pattern. Instead of composing the main object and all of its dependent objects on its own, the consumer delegates this task to a factory method, which could be a static method call in its most simple realization:

DATA lo_parser TYPE REF TO ZIF_OCR_PARSING_ALGORITHM.
lo_parser = ZCL_PARSER_FACTORY=>CREATE_NEW_PARSER( ).

 

Within CREATE_NEW_PARSER( ) the same magic takes place as before: in the first step, all low level objects are created, in the second step the main parser object is created, while its dependencies declared by the CONSTRUCTOR are satisfied. This approach is called “Poor man’s dependency injection”

 

*alternative 1: poor man's DI
DATA lo_ocr TYPE REF TO zif_ocr_parsing_algorithm.
DATA lo_char_sep TYPE REF TO zif_ocr_characters_seperator.
DATA lo_char_parser TYPE REF TO zif_ocr_character_parser.
DATA lo_file_access TYPE REF TO zif_ocr_file_access.
DATA lo_lines_seperator TYPE REF TO zif_ocr_lines_seperator.
CREATE OBJECT lo_char_sep TYPE zcl_ocr_characters_seperator.
CREATE OBJECT lo_char_parser TYPE zcl_ocr_character_parser.
CREATE OBJECT lo_file_access TYPE zcl_ocr_gui_file_access.
CREATE OBJECT lo_lines_seperator TYPE zcl_ocr_lines_seperator.

CREATE OBJECT lo_ocr TYPE zcl_ocr_parsing_algorithm
EXPORTING
io_character_parser = lo_char_parser
io_characters_seperator = lo_char_sep
io_file_access = lo_file_access
io_lines_seperator = lo_lines_seperator.

 

IoC Container

However, the task of manually creating dependent objects in order to hand them over to a course grained object when it is created, can be automated. Think of the facts that are known:

  • all low level interfaces like ZIF_OCR_CHARACTER_PARSER have one class that implements each of them
  • instances of these classes could be created dynamically, as their constructors currently require no input parameter
  • the course grained interface ZIF_OCR_PARSING_ALGORITHM also has a specific class that implements it
  • however, its constructor requires some instances of the low level interfaces
  • as these required parameters are instances of the low level interfaces, these dependencies could be satisfied automatically

 

As a brief summary, this is exactly what an IoC Container should do, also refered to as DI containers.
The registration of the interfaces and classes is done programmatically in the following example. However, it may be moved to customizing in order to “free” the code of having hard references to explizit class names

*alternative 2: IoC Container
DATA lo_ioc_container TYPE REF TO /leos/if_ioc_container.
lo_ioc_container = /leos/cl_ioc_container=>create_empty_instance( ).
lo_ioc_container->add_implementer( iv_contract = 'zif_ocr_characters_seperator' iv_implementer = 'zcl_ocr_characters_seperator' ).
lo_ioc_container->add_implementer( iv_contract = 'zif_ocr_character_parser' iv_implementer = 'zcl_ocr_character_parser' ).
lo_ioc_container->add_implementer( iv_contract = 'zif_ocr_file_access' iv_implementer = 'zcl_ocr_gui_file_access' ).
lo_ioc_container->add_implementer( iv_contract = 'zif_ocr_lines_seperator' iv_implementer = 'zcl_ocr_lines_seperator' ).
lo_ioc_container->add_implementer( iv_contract = 'zif_ocr_parsing_algorithm' iv_implementer = 'zcl_ocr_parsing_algorithm' ).

 

No matter, how the classes have been registered, either in the code or by customizing, the caller now only needs to call the container and request an instance from it at startup:

DATA lo_ocr TYPE REF TO zif_ocr_parsing_algorithm.
*create the container either by reference to customizing or by the registration coding shown above...
*...
lo_ocr ?= lo_ioc_container->get_implementer( iv_contract = 'zif_ocr_parsing_algorithm' ).

Blog It Forward - Susmitha Susan Thomas

$
0
0

I was blogged forward by Mohammed Yakub Shah and Arindam Mondal. Thanks to you for letting me participate in this innovative and exciting game of 'passing the baton' in SCN and thanks to Moshe Naveh for this wonderful initiative. I am glad I could be a link to keep this chain growing even a year (to be exact 1 year and three days ) after it was created.

 

About Me:

 

I am an SAP Consultant working in Gulf Piping Company, Abu Dhabi, UAE. Previously I was working with Wipro Technologies, Bangalore. I did not chose SAP. I was randomly put in the SAP batch among the campus recruited students batches in Wipro, for which I am very grateful to God. Coz I thoroughly love SAP and ABAP programming and am not sure if I would have enjoyed anything else as much.

 

It was only in the last one year that I started becoming active in SCN, the gamification definitely played a role initially, but then it slowly moved to that satisfaction you get in being able to help someone solve some problem in addition to the excitement of solving puzzling situations.

 

In the company I am working, I am the only SAP ABAP Consultant, and I used to feel a little lonely when it comes to SAP and ABAP but once I was active in SCN, I never felt alone : Felt I was part of an SAP family with many friends to share the experiences in SAP and ABAP. 

 

SCN soon became a part of my daily routine and if I open my browser, you can bet an SCN tab would be opened.

 

 

About my Home Land :

 

I was born in the southern most state in India, called Kerala, often known as God's Own country. Kerala is one of the most beautiful places and is a very popular tourist destination.

 

Its beauty is mostly contributed by back waters, long shoreline with serene beaches, paddy fields, waterfalls and wild life.

 

backwater  alleppey.jpg

 

 

 

 

index1.jpg

                                                                                                                 index.jpgxKerala-Tourism-Banner.jpg.pagespeed.ic.ccj9D-hCz2.jpg

A few facts about Kerala : Kerala is the state which has the highest Human Development Index (HDI) (0.790) in the country, highest literacy rate (almost 100%), the highest life expectancy (74 years) and the highest *** ratio (as defined by number of women per 1000 men: 1,083 women per 1000 men) among all Indian states. Malayalam is the most widely and official language spoken in Kerala.

 

Questions Asked :


  1. What are the best experiences that you had while being part of this community?I enjoy every moment in SAP. As mentioned before, the thrill of solving issues, is one of the best experiences : that moment when you know that your solution solved a problem, and to know that it saved someone's day makes it even more better.
  2. What are the hobbies or activities that you enjoy most? Music Music Music. I love listening to music and playing music. I can sit for hours and hours and hours on my guitar, violin and piano.
  3. What would you be if not an SAP Consultant ? - Financial and Stock Market Analyst.
  4. What was the most fun project you ever participated in and why? - It was a chatting application that we friends created in college. The amount of fun that was we used to have by chatting with the friends sitting in the same room under the noses of our lecturers was some fun. :-)


I would like to pass the baton to

Frédéric Girod

Ramesh T

Raymond Giuseppi

 

My questions to you..

  • What was your dream job as a kid?
  • Who has inspired and motivated you the most?
  • What is the most important quality that you hope to find in your colleague that will make your work place a better place?

 

To know more about BIF, refer this blog. Blog It Forward Community Challenge. Once you complete the BIF, update your details in the BIF chain -

Blog It Forward Chain

 

Regards.

Susmitha



Example for cell colors in ALV

$
0
0

HereI attachedan examplequite usefulto knowthe differentcell colorswe can giveto aALV.


 

 

*&---------------------------------------------------------------------*
*& Report  ZCELL_COLORS
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  ZCELL_COLORS.

TYPES:
   BEGIN OF ts_data,
     col   TYPE lvc_col,    " color 1-7
     int   TYPE lvc_int,    " intensified 0-1
     inv   TYPE lvc_inv,    " inverse 0-1
     scol  TYPE lvc_t_scol, " table for cell coloring
   END OF ts_data,
   tt_data TYPE TABLE OF ts_data.

DATA:
   ls_data    TYPE ts_data,
   lt_data    TYPE tt_data,
   lv_index   TYPE i,
   ls_color   TYPE lvc_s_scol,
   lt_color   TYPE lvc_t_scol,
   lo_table   TYPE REF TO cl_salv_table,
   lo_columns TYPE REF TO cl_salv_columns_table,
   lo_column  TYPE REF TO cl_salv_column_list.

* empty row with default color
APPEND ls_data TO lt_data.

* rows with possible colors
DO 7 TIMES.

   ls_color-color-col = sy-index.   " 1-7

   DO 2 TIMES.

     lv_index = sy-index - 1.
     ls_color-color-int = lv_index.   " 0-1

     DO 2 TIMES.

       lv_index = sy-index - 1.
       ls_color-color-inv = lv_index.   " 0-1

       APPEND ls_color TO lt_color.

       ls_data-col   = ls_color-color-col.
       ls_data-int   = ls_color-color-int.
       ls_data-inv   = ls_color-color-inv.

       ls_data-scol = lt_color.
       APPEND ls_data TO lt_data.
       CLEAR lt_color.
     ENDDO.
   ENDDO.
ENDDO.

TRY.
     CALL METHOD cl_salv_table=>factory
       IMPORTING
         r_salv_table = lo_table
       CHANGING
         t_table      = lt_data.

     lo_columns = lo_table->get_columns( ).

*   set descriptions of columns
     lo_column ?= lo_columns->get_column( 'COL' ).
     lo_column->set_short_text( 'COL' ).

     lo_column ?= lo_columns->get_column( 'INT' ).
     lo_column->set_short_text( 'INT' ).

     lo_column ?= lo_columns->get_column( 'INV' ).
     lo_column->set_short_text( 'INV' ).

*   set the column with the information about colors of rows and fields
     lo_columns->set_color_column( 'SCOL' ).

     lo_table->display( ).

   CATCH cx_salv_msg.             " cl_salv_table=>factory
     WRITE: / 'cx_salv_msg exception'.
     STOP.

   CATCH cx_salv_data_error.      " cl_salv_filters->add_filter()
     WRITE: / 'cx_salv_data_error'.
     STOP.

   CATCH cx_salv_not_found.       " cl_salv_columns_table->get_column()
     WRITE: / 'cx_salv_not_found exception'.
     STOP.
ENDTRY.

*------------------------------------------------

 

Regards.


Change Word table style in an Open XML document

$
0
0

Hello.

This  is another screen cast about the Open XML in SAP.

this one dealing with layout change of the MS-Word template

without any  programming changes.

it shows  how  a  change int the table style can  change the layout

of the document.

 

Open XML documents are manipulated on the SAP server

without using  MS-Word application.

 

 

 

   Ronen Almog


Open XML for SAP ver. SAP Duet

$
0
0

Hello.

I've been asked in  the last few months  about Open XML for SAP.

some of the people compared it to SAP duet

some of them said that Duet does the same functions as Open XML does.

well, i'm not an expert of Duet, but i did some research  about it and find out

that there is no common between the two.

 

Open XML for SAP  ( Office 4 Sap  )  does  creation and manipulation of Office documents and spreadsheets

on  the SAP server, Duet is an Interface between SAP and SharePoint server.

 

Open XML for SAP uses the Open XML  standards while Duet uses Odata Channel.

 

If you have any need for Office documents and spreadsheets manipulation

consider the use of Open XML for SAP.

 

 

   Cheers

 

    Ronen Almog

Blot if forward - Frédéric Girod

$
0
0

So it's my turn to play the game 'Passing the baton' (I like that, it's a french word ).

Thank you Susmitha Susan Thomas to give me the opportunity to participate to this relay and thank you Moshe Naveh to have create it.

 

 

About me:

 

I'm starting my 16 years working on SAP, I feel like that was yesterday. I remember my first working day : the 3 july 1998, a famous day in France, that was the 1/4 soccer wold cup final France - Italia.

2521693591_1.jpg

No, I don't like watching soccer on the TV, but when France win on Italia, it's always a pleasure to look that . (A special dedicate to Raymond Giuseppi

).

 

My first job on SAP was to make an 'upgrade' from an old R/2 system to a new R/3 system (3.1i). I remember my first SAP Editor (3.1), I was really surprise by the old school design of this application. You have only 14 lines on the screen, each line were independents : you can't copy/past simply the code like in notepad.

images.jpeg

Image2475.gif

 

For people who know VI(m) on Unix system, the editor looks like-it. You have a field to pass command, for example to copy a set of lines .. 

 

When I start working, there was no doc about Abap, you could only buy book in specific libraries (2 in Paris), to learn SAP you have to see how SAP works : debug the standard. There was also transaction like AbapDocu, DWDM, SE30 ..  I spend a lot of time looking the Tips & Tricks on the SE30.

 

 

After one year learning Abap I would like to work on Optimization, Performance tuning. I see a lot of young abapor going in this way, I don't know why we need to do that.

What I have learn on optimization is very simple : There are no simples rules ! The experience removes your sureness (that's thru for life also).

The  second point is : Someone will (try) to read your code, a day. If your code is too much optimized, this boy or this girl will loose a lot of time on it. And remember why you have optimized the code, to win time for your company --> to win money. And the time loosed to modify your code will cost a lot of money. So you failed ...

 

 

I was joining the SDN team on the year 2004, that was a great evolution in the Abapor world: A place to exchange learning, tips & tricks .. The big subject was the ALV, few persons know how it works and a lot of questions were on this subject. I stopped being active on SDN when I joined an end-user company, I have no enough time and I was little annoyed by people whose copy your answer .. (dedicate to Matthew Billingham who tried to keep this forum clean)

I really don't understand why some people need to post an answer already given. You could give more information, examples, but ... just copy the same answer ... nonsense ..

 

After 6 years in a big chemical industry I decided to return to consulting. I think the job is more simple when you are consultant. You work to help people finding solutions on their problems, simply. You have much more time to learn new technics on SAP, and more time to go in SDN.

 

 

 

Me in private :

 

I'm leaving in France, near to the town of Lyon.

305060_10151113403472302_865172919_n.jpg

It a nice place for people rides on mountain bike and running. In this part of France there is a lot of cherry tree and raspberry.

 

 

My son :

736225_10151332099227302_1762078030_o.jpg

 

And my daughter :

965429_10151646250697302_974539997_o.jpg

 

 

When I'm not at work I like DIY, and specially on wood. This is the first stairway I have build in beech.

778694_10151375162927302_1640403473_o.jpg

798180_10151375162692302_1435137589_o.jpg

Thrust me, it's really harder than coding on Solman

 

 

 

The questions : 

 

 

The dream job when I was kid : 

I just want to fly like the movie Top Gun , but I stop very quickly this dream, I'm Seasickness in plane

Top_Gun_large_verge_medium_landscape.png

 

Who has inspired and motivated the most :

Hugh ... little hard question. I was a Linuxian when I was young, a real addict to the penguin. I was really impress by the job of some teams. For example the Enligthenment team and Mr Rasterman.

 

What is the most important quality that you hope to find in your colleague that will make your work place a better place?

A very good question, it's really hard to find good Abapor. I think it's like the optimization, I prefer to have people who respect the coding, who write clean code instead of a "geek" coder who like to make inner join with 6 tables and use field-symbols every where

 

 

 

I would like also to see the blog of :

Ramesh T

Raymond Giuseppi

 

 

My questions :

 

- What would like to find in SCN ? What would you like SCN looks like ? What will you change on SCN ....

- What is your worst coding program ? The program you would like never to modify ... ?

 

 

 

To know more about BIF, refer this blog. Blog It Forward Community Challenge.

Once you complete the BIF, update your details in the BIF chain - Blog It Forward Chain

 

 

 

 

Regards

Fred

 

 


Get the data types of all fields in a table

$
0
0

Hello everyone,

 

After some research I've managed to find an answer to my own question here:

http://scn.sap.com/thread/3412096

and I would like to share this with you.

Basically, in oder to find the types of all fields of a given table, just make the following query to table DD03L:

SELECT tabname fieldname rollname

     INTO TABLE some_table

     FROM DD03L

     WHERE tabname = some_name.

 

BUT, sometimes, fields might be either a structure, or a table as well (deep table\structure). In those cases, we need to select the field type from tables DD03M (if structure) or DD40L (if table). Here are examples:

SELECT typename rowtype

     INTO TABLE some_other_table

     FROM DD40L

     WHERE typename = some_row_from_some_table-rollname.

OR

SELECT tabname fieldname rollname domname

     INTO TABLE some_other_different_table

     FROM DD03M

     WHERE tabname = some_row_from_some_table-rollname.

 

Note the differences between the two queries.

 

Any additions, corrections, or maybe a name of an existing function that does all that faster and easier, will be appericiated!

Hope that helps someone

Blog if forward - Ramesh.T

$
0
0

I was blogged forward by Susmitha Susan Thomas and Frédéric Girod, Thank you for this opportunity to me participate in this exciting game of 'passing the baton' in SCN and thanks to Moshe Naveh for this wonderful initiative.

 

About Me:


I am an SAP Consultant working in Lanco, Andhra Pradesh, India. With SAP my association last 7 years, after completing my education I joined in Lanco, at that time I don’t know about SAP. After joining, my company started SAP implementation. During implementation I got opportunity to learn SAP ABAP and I continued as ABAP Consultant. I love SAP and ABAP Programming.


Association with SCN for last five months, I enjoying a lot with SCN when giving solutions, someone makes my answer as correct and getting solution. Before SCN I feel alone in my job, now I was part of an SAP family with many friends to share the experiences in SAP and ABAP. I always thankful to Matthew Billingham for showing me a right path. Now SCN become part of my life.

 


 

About my Home Land :


I was born in Andhra Pradesh, India; Andhra Pradesh is india’s fourth largest state by area and fifth largest state by population, our capital Hyderabad,  Andhra Pradesh is bordered by Maharashtra, Chhattisgarh and Orissa in the north, the Bay of Bengal in the east, Tamil Nadu to the south and Karnataka to the west.


It is historically called the "Rice Bowl of India".More than 77% of its crop is rice; Andhra Pradesh produced 17,796,000 tonnes (19,616,732 short tons) of rice in 2006. Two of the mega cities of the state - Hyderabad and Visakhapatnam - were listed among the top 15 cities contributing to India's overall Gross domestic product. On 1 November 1956, the States Reorganisation Act formed Andhra Pradesh by merging the Andhra State with the Telugu-speaking areas of already existing Hyderabad State.

 

 

 

 

 

Questions Asked :

  • What was your dream job as a kid?

            Scientist like Albert Einstein 

  • Who has inspired and motivated you the most?

            My Parents

  • What is the most important quality that you hope to find in your colleague that will make your work place a better place?         

            I feel team work on resolving critical issues, helping nature on helping other’s when

            they are facing problems and try to learning new things.   

 

 

I would like to pass the baton to

Raymond Giuseppi

Matthew Billingham

Smruti Ranjan Mohanty

 

My questions to you..

  • What quality’s required to be a good ABAP Programmer.
  • Had you not been into software at all, where would you have been?
  • What is your best moment in life?
  • Who has inspired and motivated you the most?

 

To know more about BIF, refer this blog. Blog It Forward Community Challenge. Once you complete the BIF, update your details in the BIF chain - Blog It Forward Chain

 

Once again tanks to all for giving this opportunity..


Regards,

Ramesh.T

Things to be taken care on creating custom Check printing in SAP – SAP Script F110_PRENUM_CHCK

$
0
0
  1. Create a custom copy of F110_PRENUM_CHCK
  2. Create a subroutine pool in SE38, to achieve
    logic changes in the SAP Script even without modifying the standard driver
    program RFFOUS_C
  3. While commenting existing standard scripts, make
    sure that the mentioned element should not get deleted, even though you are not
    going to display anything under this element. Instead you can add one commented
    text under the respective elements.
  4. Say for example, if you need to display the
    remittance section as a table, then it is always a good practice to keep the
    BOX comments for drawing lines in the main window as one separate window. The
    following is some example code to draw a table with Five columns:

 

           Vertical Lines

 

/:           BOX XPOS 0 MM YPOS 0 MM WIDTH 0 TW HEIGHT 138 MM FRAME 10 TW

/:           BOX XPOS 27 MM YPOS 0 MM WIDTH 0 TW HEIGHT 138 MM FRAME 10 TW

/:           BOX XPOS 70 MM YPOS 0 MM WIDTH 0 TW HEIGHT 138 MM FRAME 10 TW

/:           BOX XPOS 113 MM YPOS 0 MM WIDTH 0 TW HEIGHT 138 MM FRAME 10 TW

/:           BOX XPOS 149 MM YPOS 0 MM WIDTH 0 TW HEIGHT 138 MM FRAME 10 TW

/:           BOX XPOS 192 MM YPOS 0 MM WIDTH 0 TW HEIGHT 138 MM FRAME 10 TW

 

          Horizontal Lines

 

/:           BOX YPOS 0 MM WIDTH 192 MM HEIGHT 0 TW FRAME 10 TW

/:           BOX YPOS 10 MM WIDTH 192 MM HEIGHT 0 TW FRAME 10 TW

 

          Sum total Row

/:           BOX YPOS 130 MM WIDTH 192 MM HEIGHT 0 TW FRAME 10 TW

/:           BOX YPOS 138 MM WIDTH 192 MM HEIGHT 0 TW FRAME 10 TW

 

 

    5.   For putting frame to a window, we can use thefollowing:

 

/:           BOX FRAME 30 TW

How to create a RoadMap in GUI environment

$
0
0

Hi guys,

 

This is my first blog and I found an interesting subject one week ago about RoadMap but in GUI environment, normally Roadmap is used with Web Dynpros.

 

This is the code of my program

 

*---------------------------------------------------------------------*
 * Description                                                                    *
 *--------------------------------------------------------------------*
 * Program      : YTEST_ROADMAP                               *
 * Author          : David Carballido Córdova                   *
 * Date             : 22/08/2013                                              *
 * Comentarios   : Build and show Roadmap             *
 *--------------------------------------------------------------------*
 REPORT ytest_roadmap.

 PARAMETERS: p_steps TYPE i OBLIGATORY.
 *----------------------------------------------------------------------*
 *       CLASS DEFINITION DEFERRED
 *----------------------------------------------------------------------*
 CLASS: lcl_main  DEFINITION DEFERRED,        lcl_event DEFINITION DEFERRED.

 *----------------------------------------------------------------------*
 *       Global Variables
 *----------------------------------------------------------------------*
 DATA: go_main TYPE REF TO lcl_main,       g_state TYPE /use/ugu1_state,       g_text  TYPE char40.

 *----------------------------------------------------------------------*
 *       CLASS lcl_main DEFINITION
 *----------------------------------------------------------------------*
 CLASS lcl_main DEFINITION FINAL.   PUBLIC SECTION.     METHODS: start_road,              state_click IMPORTING i_state_id TYPE /use/ugu1_state,              next_step.   PRIVATE SECTION.     METHODS: init_roadmap.     DATA: go_roadmap TYPE REF TO /use/cl_ugu1_html_roadmap,           go_custom  TYPE REF TO cl_gui_custom_container,           go_event   TYPE REF TO lcl_event.

 ENDCLASS.                    "lcl_main DEFINITION

 *----------------------------------------------------------------------*
 *       CLASS lcl_event DEFINITION
 *----------------------------------------------------------------------*
 CLASS lcl_event DEFINITION FINAL.   PUBLIC SECTION.     METHODS: state_click FOR EVENT evt_state_click                 OF /use/cl_ugu1_html_roadmap                     IMPORTING i_state_id.

 ENDCLASS.                    "lcl_event DEFINITION

 *----------------------------------------------------------------------*
 *       CLASS lcl_main IMPLEMENTATION
 *----------------------------------------------------------------------*
 CLASS lcl_main IMPLEMENTATION.   METHOD start_road.     IF go_custom IS INITIAL.
* Instance Container       CREATE OBJECT go_custom         EXPORTING           container_name              = 'ROADMAP'         EXCEPTIONS           cntl_error                  = 1           cntl_system_error           = 2           create_error                = 3           lifetime_error              = 4           lifetime_dynpro_dynpro_link = 5.       IF sy-subrc = 0.
* Instance Roadmap         CREATE OBJECT go_roadmap           EXPORTING             i_parent            = go_custom             i_application_event = abap_true           EXCEPTIONS             cntl_error          = 1.         IF sy-subrc <> 0.           EXIT.         ENDIF.
* Instance Event Class         CREATE OBJECT go_event.         SET HANDLER go_event->state_click FOR go_roadmap.
 *  Initializing Roadmap         me->init_roadmap( ).
 * Set  Width of Roadmap         go_roadmap->set_state_width( i_width = '40' ).
 * Generate HTML of Roadmap         go_roadmap->render( EXCEPTIONS render_error = 1 ).       ELSE.         EXIT.       ENDIF.     ENDIF.   ENDMETHOD.                    "start_road   METHOD init_roadmap.
 * Local Variables     DATA: l_step TYPE numc2,           l_text TYPE char30.
* Initializing States     go_roadmap->remove_all_states( EXCEPTIONS remove_failure = 1 ).     DO p_steps TIMES.       l_step = sy-index.       CONCATENATE 'Step' l_step INTO l_text SEPARATED BY space.       go_roadmap->add_state(         EXPORTING           i_state_text   = l_text           i_state_type   = /use/cl_ugu1_html_roadmap=>c_state_normal           i_is_clickable = abap_true           i_is_optional  = abap_false         EXCEPTIONS           add_failure    = 1 ).     ENDDO.
 * Activate first state     IF g_state IS INITIAL.       go_roadmap->set_state_type(         EXPORTING           i_state_id     = '1'           i_state_type   = /use/cl_ugu1_html_roadmap=>c_state_active         EXCEPTIONS           invalid_state  = 1           update_failure = 2 ).
 * Send initial text       g_text = go_roadmap->get_state_text( '1' ).     ELSE.       go_roadmap->set_state_type(         EXPORTING           i_state_id     = g_state           i_state_type   = /use/cl_ugu1_html_roadmap=>c_state_active         EXCEPTIONS           invalid_state  = 1           update_failure = 2 ).     ENDIF.   ENDMETHOD.                    "init_roadmap   METHOD state_click.     g_state = i_state_id.
 * Get text of state      g_text = go_roadmap->get_state_text( i_state_id ).
 * Free Objects     go_roadmap->free( ).     go_custom->free( ).
 * Clean Objects     CLEAR: go_roadmap, go_custom.
 * Simulate ENTER to refresh screen     cl_gui_cfw=>set_new_ok_code( '/00' ).   ENDMETHOD.                    "state_click   METHOD next_step.
 * Local Variables     DATA: lt_states TYPE /use/ugu1_t_roadmap_state,           l_state   TYPE /use/ugu1_state.     FIELD-SYMBOLS: <fs_states> TYPE /use/ugu1_s_roadmap_state.
 * Get active state     go_roadmap->get_states_by_type(       EXPORTING         i_state_type = /use/cl_ugu1_html_roadmap=>c_state_active       IMPORTING         et_states = lt_states ).     READ TABLE lt_states ASSIGNING <fs_states> INDEX 1.     IF sy-subrc = 0.       l_state = <fs_states>-state_id + 1.
 * Get residue on parameter selected       l_state = l_state MOD ( p_steps + 1 ).       IF l_state = 0.         l_state = 1.       ENDIF.
 * Set state click       me->state_click( l_state ).     ELSE.       MESSAGE s888(sabapdocu) WITH 'No existe paso activo'.     ENDIF.   ENDMETHOD.                    "next_step
 ENDCLASS.                    "lcl_main IMPLEMENTATION

 *----------------------------------------------------------------------*
 *       CLASS lcl_event IMPLEMENTATION
 *----------------------------------------------------------------------*
 CLASS lcl_event IMPLEMENTATION.   METHOD state_click.     go_main->state_click( i_state_id ).   ENDMETHOD.                    "state_click

 ENDCLASS.                    "lcl_event IMPLEMENTATION

 *----------------------------------------------------------------------*
 *       S T A R T  -  O F  -  S E L E C T I O N
 *----------------------------------------------------------------------*
 START-OF-SELECTION.
 * Instance Main Class   CREATE OBJECT go_main.
 * Show Roadmap   CALL SCREEN 100.

 *&---------------------------------------------------------------------*
 *&      Module  STATUS  OUTPUT
 *&---------------------------------------------------------------------*
 MODULE status OUTPUT.   SET PF-STATUS 'ST_100'.   SET TITLEBAR 'TIT_100'.
 * Show Roadmap   go_main->start_road( ).

 ENDMODULE.                 " status  OUTPUT

 *&---------------------------------------------------------------------*
 *&      Module  user_command  INPUT
 *&---------------------------------------------------------------------*
 MODULE user_command INPUT.   CASE sy-ucomm.     WHEN 'BACK'.       LEAVE TO SCREEN 0.     WHEN 'NEXT'.       go_main->next_step( ).   ENDCASE.

 ENDMODULE.                 " user_command  INPUT

 

Here I attach screen 100 to upload and generate

Dynpro_1.jpg

Dynpro_2.jpg

Then when you execute the program you can select how many steps are going to build, for example I'll select 10

Dynpro_3.jpg

And this is the result

Dynpro_4.jpg

You can click on any step or press "Next Step" button to select the next step, I hope this help you in any development and I welcome your comments

 

PD: Sry for my bad english

 

Regards

David Carballido

ABAP Adventure Games Framework - Part 1 - "Introduction"

$
0
0

Yes, you read it right: this blog is about ABAP and Games. I know a few people already implemented their own games using ABAP, but I always felt I also had to make a little contribution into this area. In fact, I tried doing a "contribution" by myself, but something happened along the way and I had to change my plans. In this blog I'll tell you what happened, what are my ideas, and how you can help along the way.

 

 

AS Trial Nightmares

 

Before explaining my motivations for doing an adventure game, I must say I already made this game framework using ABAP, in 2011.  But one pretty day I started my AS Trial VM and got to know that my MaxDB got corrupted, and I lost everything I had inside my AS Trial installation. I made that classical error of not backing up my sources outside the SAP system, and I got extremely mad about it. I even presented my game at the SAP Inside Track São Paulo we had in 2011, so you can imagine how nervous I got about my dumb mistake.

 

The only thing I have left of that prototype is a video I made for my own ABAP blog:

 

(it's brazilian portuguese, but you can get the idea)

 

I want to make that game again, but this time I do not want to make it all by myself. That's why I'm writing this blog: I want to get help from the community!

I'm a huge fan of OO developments, but I'm far away from being an expert. Hopefully this crazy idea can raise good discussions about software architecture, development practices and OO concepts, making me (and maybe you!) a better developer when things are finished.

 

Ready? Let the game begin!

 

 

1. Motivation

 

"Man, are you nuts? Making an ABAP game with old and ugly 'WRITE reports' when we have things like HANA, UI5, SUP, bla, bla, bla, bla?".

 

My first contact with computers where through DOS games. I remember getting extremely excited whenever my father said we were going to my grandmother's house, because I knew I would get a change of playing a game in my aunt's "bright new" 486 computer ( yeap, she was always very cool to all of her nephews). One of my siblings got a friend who could install games using 20 (or something) floppy disks, and every couple of months he came and added a few gems to my aunt's game library. That's how I got to know Warcraft, Doom, Castle Wolfenstein and Hexen.

 

But then I played a game that made me crazy about that genre until today. It all started with a little purple tentacle trying to dominate the whole world:

 

http://upload.wikimedia.org/wikipedia/en/thumb/7/79/Day_of_the_Tentacle_artwork.jpg/250px-Day_of_the_Tentacle_artwork.jpg

I still finish this game every couple of years, using scummvm

 

 

How the game works: you got some "actions" in the bottom side of the screen,, and you move forward in the game by talking to NPCs, finding new areas, combining items and using them at the right places. The NPC characters always give you clues about what you have to do next... however, can you imagine how hard it was for a 11 years old brazilian boy to solve those puzzles? As you are seeing (or reading?) I'm not a native english speaker/writer, and I didn't even know what english was about back in those days. Basically I used a lot of my time trying to do every little combination I could to advance. I'm not sure why I just didn't drop it and went back to Doom, but I guess some things are not meant to be explained.

 

Then I played things like Monkey Island, Indiana Jones and The Fate of Atlantis, Loom, Sam & Max... and I kept playing this kind of stuff until today, and the odds are I'll never stop loving this game genre (btw, try playing Machinarium it's EXTREMELY AWESOME!).

 

So every since I started programming, I always wanted to make an Adventure Game. Now, I could use some new and fancy stuff to implement this idea, but it's not about being opposite to new tools and products, it's more about gaming retro-style. Also, ABAP lists are surely *not* made for animated stuff, so it's kinda fun to overcome those limitations.

 

 

2. Framework

 

You understood by now that I want to do my own game, but Luca's Art's master move was making a engine that could be applied to many games. That's how they could launch that tremendous amount of awesome titles in a short period of time, throwing new stories at us without having to teach us how to play each of those games individually (remember: internet wasn't THAT popular at the 90's). Whenever something new was launched, you instantly got the idea and was able to play the new game from start to finish. Today that engine is shared through scummvm, please take a look if you're into that kind of geek old stuff.

 

I cannot make a huge thing like this a game engine inside SAP, but I can create a framework for adventure games using ABAP. A main program and a set of classes responsible for launching the adventure game, and serving automated methods for handling rooms, screen objects, actions, messages and such. The game you saw on the video, "Zombie Attack", was made using an initial prototype of that framework - the one I lost when my installation crashed.

 

 

3. Community Help

 

It's good to create something by yourself, but I feel I can get a lot more from this project if I share the steps of making this framework here on SCN. It will be a blog like this one, sharing the UML diagrams, initial prototypes and the source code.

 

Now that the Code Exchange is shutting down, I'm not sure where I could post releases and the final version, but this is something that will hopefully be covered by the end of this project. In the mean time, I'll use blog posts to share the progression.

 

I'll definitely hear you, so please, do share your thoughts to improve my work. Like I said I'm far away from being an expert in OO, UML, etc, so any suggestions are welcome. Of course I won't change every little thing, but that's the joy of discussing development topics (check this and this - I can spend days into good discussions!).

 

 

4. Next Steps

 

I already started drawing the UML class diagram for this project. I'll also explain in details how things are going to work inside the framework (like rooms, actions, etc). I do not want to give any dates (we're all busy on the SAP world), but let's just say I'll do my best to release it by the end of next week. If you have any ideas for this project, please share through comments.

 

The "POC game" I want to implement using my framework is "Zombie Attack". Everybody loves a Zombie Game these days, right?   The version on that video is not using any items (like a shotgun, shells, tools, etc..), but I'm thinking about adding something to handle them. Let's see how far I can get.

 

One thing I would love to see is someone else making their own game using the final framework. Even if it's a two-room game, it would make me extremely happy (that's a personal goal for this project).

 

I'll also cross-post some of the information from this blogs on my personal ABAP blog. We have a cool community in Brazil, but sadly most people still have the language barrier to use SCN, especially abap noobs (beginners). I'll do my best to forward them to where things are really happening.

 

 

Thanks for reading, and stay tuned for more gaming!


A Quick View on different SPs of SAP NW 7.31 regarding Quality & Disruptiveness

$
0
0

For me as software architect the last time has been really difficult – I was uncomfortable about the quality of AS ABAP software components. I spend too much time analyzing errors and in for some of them there working but not satisfying solutions. One source of the problems are disruptions which I mentioned on SCN and I told you that fortunately SAP could help in many cases.

 

In the meantime I learned that some of my calculations are in favor of SAP because I encountered a kind of “morass” in software components that was deleted and didn’t occur in my statistics because it consists of elements that are not assigned to a software component and therefore don’t appear in my statistics.

 

Then I had the feeling that some SPs of NW 7.31 had a terrible quality– especially SP4 and SP5 because in two strategic frameworks disruptive errors have been shipped and in another strategic frameworks the number of OSS messages much too high. I had mixed feelings when looking at different SPs of NW 7.31 and I am asking what happened here. Of course I can only guess but I don’t trust my impression so I tried to find out what was going on.

 

Nearly no Deletions from SP 5 to SP 8

My first question was whether SAP continued to delete the platform and I was surprised. At first some good news: from SP5 to SP8 there have been no deletions in SAP_ABA - congratulations!  The number of TADIR objects grew from 47.871 objects to 48.347 objects which is under 1% new development. The same is true for SAP_BASIS: I found only 385 deletions, but if you look at the deletions then you will find many classes like CL_EPM_PD_UPLOAD_FORM_FEEDER which belong to NetWeaver demo application. The software component grew from 251.069 to 254.040 which is roughly 1%.

 

What happened from SP5 to SP8?

It seems to me that from SP5 to 8 SAP fixed bugs but didn’t neither ship new functionality nor deleted anything. It seems to me that in these SPs only bugs have been fixed which is the purpose of an SP.

 

This is quite in line with my personal experience. My first test of NW 7.31 software started with SP3 and I didn’t found any problems. In SP4 and SP5 I encountered some severe problems. Thanks to SAP they have been solved in OSS notes and in SP6, 7 and 8. From my experience upgrading to SP8 was a good decision.

 

My Personal Conclusion

I experienced the following:

  • some SPs (especially 4 and 5) had a very poor quality
  • at the moment I can’t predict the costs of a SP upgrade in terms of test effort
  • upgrading to some SPs has been more problematic than implementation of some Ehps

At the moment I am a bit helpless. My former strategy of estimating disruptivity of Ehps early (and at a low SP level is failing) because everything can change with a new SP. As consequence at the moment some SPs require so much test effort that I’m thinking of additional investments in automated software tests.

 

The reasons is simple: I expect that new frameworks can be unstable but bug in strategic frameworks that are foundations of business solutions are fatal.

 

My Advice to SAP: Improve the Quality of SPs and keep an Eye especially on old Code

I hope that SAP will continue the strategy to prevent deletions.

 

I think customers will embrace new SAP NetWeaver features in SPs as long as the platform remains stable. But achieving high software quality and stability should be highest priority. And from experience there is much room for improvement - especially the quality of SP4 to 7 was poor from my experience.

 

For me it is especially annoying that some changes in old code had drastic and negative effects on stability. In my opinion SAP should change old code only if the following preconditions are met:

  • the change is compatible and so no disruption will occur and
  • the change has been thoroughly tested.

Dependency Injection for ABAP

$
0
0



Dependency Injection for ABAP:

Loose Coupling and Ease of Testing

Overview

What Is Dependency Injection?

Unit testing is often made more difficult by the heavy use of classes as namespaces and the proliferation of static methods to encapsulate configuration code.

Dependency injection is a design pattern that shifts the responsibility of resolving dependencies to a dedicated dependency injector that knows which dependent objects to inject into application code. Dependency injection offers a partial solution to our problem, by offering an elegant way to plug in either the new objects taking over the responsibilities of static methods, or others required for testing purposes.

[Niko Schwarz, Mircea Lungu, Oscar Nierstrasz, “Seuss: Decoupling responsibilities from static methods for fine-grained configurability”, Journal of Object Technology, Volume 11, no. 1 (April 2012), pp. 3:1-23, doi:10.5381/jot.2012.11.1.a3.]

Why Use Dependency Injection?

Some of the benefits of dependency injection in the ABAP context include:

  • Loose coupling of code
    • An application knows about an interface, and only deals with the interface. The dependency injection system is responsible for hooking the interface reference up to an actual instance of functionality.
  • Ease of testing
    • The dependency injection system can be triggered so that it only instantiates test implementations and mock functionality. This means a developer can test the real system with some functionality switched out, easing testing of parts of a system.

In a real world scenario, dependency injection could be used in parts of an application such as accessing configuration data or handling reading and writing of application data to the database. In a testing scenario, we need to test using a specific configuration for predictable results. We also may not want to save data on the database, and we may depend on specific data being used for tests. Using dependency injection, we can ensure a known and stable configuration is used during the test, and use specific mock data provided instead of data directly from the database, to make sure the data is processed as required.

Dependency Injection in Action

Using RTTI and some Object Oriented Data Dictionary metadata stored within SAP, a straightforward and easy to use approach can be taken to implement this functionality. In this section we have code snippets outlining the approach taken, including UML diagrams. The entire working example can also be downloaded for installation and experimentation.

An Example Report

We will start with an example of dependency injection in action using a basic report. For our simple program, we have an interface containing some business logic, in this case configuration data, called zdi_if_config. We have several implementations of the interface, each of which is intended for a different scenario. For everyday use, we want our application to instantiate the default class, zdi_if_config_def. Another department would like the functionality to behave a little differently, but we don’t want to go straight in and modify our default class, so we create zdi_if_config_cust which descends from the default class and replaces some of the functionality. Finally, when we’re testing our application we want to modify how the default class works, returning test data so we can be sure the environment is not affecting how the application runs – for example, providing a static configuration so we know exactly what behaviour to expect when testing. For this purpose, we have the zdi_if_config_test class.

 

[UMLRelationshipHierarchy.png]

 

The application itself is not responsible for instantiating instances of our interface – this is passed off to the dependency injection system, which makes a decision from the available implementations of an interface and instantiates an instance of a class accordingly.



Note: It is worth highlighting the fact that despite discussing the different implementing classes above, the program itself knows nothing of these implementations, and contains no references at all to these types. From the point of view of the program, the interface zdi_if_config is the only known type and the only type dealt with. This is one of the benefits of dependency injection – the program is now very loosely coupled to the implementation of the functionality. All the program needs to know is that there’s a contract for some behaviour it needs, how that contract is fulfilled doesn’t matter to the program.


 

For this example, we have a data variable which references our interface. The dependency injection system will automatically create an instance for the variable, the underlying functionality depending on the scenario (in this case, a declaratively defined mode.)

 
data:
    lif_config
typerefto zdi_if_config.


We start in standard mode – here we always use the default class unless an alternative implementation has been specified. We will inject an instance into the variable, and the expected outcome is a reference containing an instance of the alternative class.

 

  inject:
    lif_config.
" instantiates alternative class

 

In this case, lif_config will contain an instance of zdi_if_config_cust. Next, we will go into test mode, and repeat the same procedure. When asking for a reference to our interface, the system finds the test class and instantiates this. 

 

  clear lif_config.
  test_mode.
" indicates we want a class tagged with test tag
  inject:
    lif_config.
" instantiates test class

 

In this case, lif_config will contain an instance of zdi_if_config_test. Finally, we will go into pure mode. Here, we want to ignore any alternative implementations and use only default implementations. Pure mode is useful for when we have developed alternative implementations, but need to use the original default implementation for some reason.

 

  clear lif_config.
  pure_mode. " indicates we want a class tagged with default tag
  inject:
    lif_config.
" instantiates default class

 

In this case, lif_config will contain an instance of zdi_if_config_def.



Note: The different modes have been declaratively defined, but they could just as easily be configured, allowing dynamic alteration of how the application instantiates instances without code changes. The actual functionality to use could also be configured, for example specifying that a certain class should be instantiated when a specific user requests an instance for a specific interface.


Unit Testing

In normal operation, the injection would be performed only once per scope. The functionality may be needed in several places throughout the application, and the variable would be injected in all the places required. If a test scenario is needed, the DI test mode would be entered once at the beginning of the unit test (during set-up) and then the application objects would be instantiated. Every time the application requested an instance for the configuration, a test instance would be provided by the DI.

 

class bigapp_app_unit_test definitionfor testing.
 
privatesection.
   
class-data:
      mif_app
typerefto zbigapp_if_cntrl.
   
class-methods:
      class_setup.
   
methods:
      test_printing
for testing.
endclass.

class bigapp_app_unit_test implementation.
 
method class_setup.

   
data:
      lif_mod
typerefto zbigapp_if_model.


* safe in the knowledge that the app will use the test configuration
* and any other test injectables we have, such as database persistence
* overriding classes or a dummy user interface implementation.
    test_mode.

* instantiate the application model. The injection is performed

* inside of this call.

    lif_mod = zbigapp_cl_model_fact=>load(
     
exporting
        i_key =
'0042/DMO/000/00' ).

* instantiate the application controller.
    mif_app = zbigapp_cl_cntrl_fact=>create(
     
exporting
        i_model = lif_mod ).

 
endmethod.

 
method test_printing.

 

* make sure the test device is configured for the app.
* the real IMG configuration may have an alternative value
* for the current user, but the test configuration class
* overrides this so we use a specific device during testing.


    cl_aunit_assert=>assert_equals(
      act = mif_app->m_device
     
exp = 'TEST_DEVICE'
      msg =
'Test device was not configured for application').


* tell the application to print some data.
    mif_app->action( zbigapp_if_cntrl=>mcc_print ).


* check our test device to see whether the data was ok.
    cl_aunit_assert=>assert_equals(
      act = zbigapp_test_device=>m_printdata_ok( )
     
exp = 'X'
      msg =
'Test device reports print data was not ok').
 
endmethod.   
endclass

Implementation Approach

Here we will look at the implementation of the injection functionality. The inject command is simply a macro that passes the reference along to a static class method called zdi_cl_injection=>create_inst( ). The single changing parameter is called c_ref, of type any.

 

method create_inst.

 
data:
    li_ifcl_items   
type mt_classlist_tt,
    lvc_ifcl_item   
type mt_classitem,
    li_tags         
type mt_taglist_tt,
    lr_tag          
type mt_tagitem,
    lr_map          
type mt_classmap,
    lcl_descr_ref   
typerefto cl_abap_refdescr,
    lcl_abap_typdscr
typerefto cl_abap_typedescr.


First, we get some type information using the SAP RTTI system. We need to determine the type of the variable passed in, to make sure it’s a reference and get the dictionary name of the underlying interface or class.


* determine the dictionary type of the reference that was passed in.

  lcl_descr_ref ?= cl_abap_refdescr=>describe_by_data( c_ref ).
  lcl_abap_typdscr = lcl_descr_ref->get_referenced_type( ).

  lvc_ifcl_item = lcl_abap_typdscr->get_relative_name( ).

 
if lvc_ifcl_item isinitial.
   
raise nondictionary_type.
 
endif.


Next, we check our cache of previously requested instances. If a class has already been determined for this functionality, then we simply instantiate the class and return the instance.


* check our cache..
 
readtable mi_cache into lr_map
   
withkey source = lvc_ifcl_item.

 
if sy-subrc eq0.
   
create object c_ref type (lr_map-target).
   
return.
 
endif.

  lr_map-source = lvc_ifcl_item.


Next, we vary behaviour depending on whether the reference passed in is a reference to a class of interface. We are building up a list of potential instance candidates, so when a class is passed in we simply add it to the list (and we’ll look up descendants in a later step.) If an interface was passed in, we fetch a list of all classes that implement the interface (using table vseoimplem.)


* input can be a class or an interface whose imp'ing classes we want.
 
case lcl_abap_typdscr->type_kind.

   
when cl_abap_typedescr=>typekind_class.

     
append lvc_ifcl_item to li_ifcl_items.

   
when cl_abap_typedescr=>typekind_intf.

      get_imp_classes(
" classes that implement the passed in interface
       
exporting
          i_interface = lvc_ifcl_item
       
importing
          e_classes = li_ifcl_items
      ).

   
whenothers.
     
raise not_a_reference.
 
endcase.

Next, we explode the dependency tree of the classes we have collected (using table vseoextend.) This is required as the technique we use for selecting implementers of an interface only returns the classes directly implementing an interface, and not the descendants which do not explicitly define the implementation of the interface. Also, if a class reference was passed in then we need to fetch the potential candidates, which would consist of descendants of the class.

 

explode_descendents( " get entire descendant tree.
   
changing c_classlist = li_ifcl_items ).

 
if li_ifcl_items isinitial.
   
raise no_implementing_classes.
 
endif.


Next, we analyse the class list and determine any tags associated with them (using table seotypepls, which contains the forward declaration list which we have hijacked for tagging!) Possible tags include being flagged as a default class, an alternative class or a test class.
 

fetch_class_tags(
   
exporting
      i_classlist = li_ifcl_items
   
importing
      e_taglist = li_tags
  ).


Next, we apply our selection logic – if we are in test mode, we look for a test class; if we are in pure mode we look for a default class; otherwise we look for an alternative class, failing that a default class, and failing that the first class in the list.


 
do.
   
case mvb_mode.
     
when mcc_mode_test.
* if we're in test mode, read first test class if exists.
        get_target_with_tag mcc_tag_tst.
     
when mcc_mode_pure.
* if we're in pure mode, read first default class if exists.
        get_target_with_tag mcc_tag_def.
   
endcase.

* see if an alternative class exists.
    get_target_with_tag mcc_tag_alt.

* see if we have a class marked as standard.
    get_target_with_tag mcc_tag_def.

* fall through, when no keywords found just return first class.
   
readtable li_ifcl_items into lvc_ifcl_item
     
index1.
   
exit.
 
enddo.

 
if lvc_ifcl_item isinitial.
   
raise no_implementing_classes.
 
endif.


Next, we instantiate the class we want to use, and put the reference into c_ref.


 
try.
     
create object c_ref type (lvc_ifcl_item).
   
catch cx_sy_create_object_error.
     
raise instantiation_failed.
 
endtry.


Finally, we cache the name of the class and map it to the name of the type of the reference that was passed in.


  lr_map-target = lvc_ifcl_item.
 
append lr_map to mi_cache.

endmethod.

 

Downloads

Files containing the implementation can be found on the project page: https://bitbucket.org/zmob/di/downloads. This includes two SAPLink nuggets. Install NUGG_ZDI_IF.nugg first - you'll need the interface extension for SAPLink; then install NUGG_ZDI.nugg.

Next Steps (Future Articles)

  • Injecting constructor parameters on the fly
  • Configuration based selection of implementing functionality
  • Containers for managing lifecycle of objects

 

----

Test Report

report zdi_prog.

 

data:

  lvs_msg type string.

 

define inject.

*> &1 ref to interface or class

  zdi=>create_inst(

    changing c_ref = &1 ).

  assert &1 is not initial.

end-of-definition.

 

define test_mode.

  zdi=>test_mode( ).

end-of-definition.

 

define pure_mode.

  zdi=>pure_mode( ).

end-of-definition.

 

define prn.

*> &1 obj to test

  lvs_msg = &1->test( ).

  write lvs_msg.

  new-line.

end-of-definition.

 

start-of-selection.

 

* we have the business logic interface:

*   ZDI_IF

* we have business logic classes implementing ZDI_IF:

*   default (standard, from us) ZDI_DEFAULT

*   alternative (customer)      ZDI_ALTERNATIVE

*   test (for units)            ZDI_TEST

 

  data:

    lcl_di1 type ref to zdi_default,

    lif_di2 type ref to zdi_if,

    lcl_di3 type ref to zdi_default,

    lif_di4 type ref to zdi_if,

    lif_di5 type ref to zdi_if.

 

* the business logic class that is instantiated varies depending on the

* mode we are in. Within Unit tests, the test mode could be activated

* and any configuration and persistence classes could be switched out.

 

  inject:

    lcl_di1, " instantiates alternative class ZDI_ALTERNATIVE

    lif_di2. " instantiates alternative class ZDI_ALTERNATIVE

 

  test_mode. " indicates we want a class tagged with test tag

  inject:

    lcl_di3, " instantiates alternative class ZDI_ALTERNATIVE

    lif_di4. " instantiates test class ZDI_TEST

 

  pure_mode. " indicates we want a class tagged with default tag

  inject:

    lif_di5. " instantiates default class ZDI_DEFAULT

 

  prn:

    lcl_di1, " alternative - alternative is a descendant of default

    lif_di2, " alternative - alternative implements interface

    lcl_di3, " alternative - test class is not related to default

    lif_di4, " test - test implements interface

    lif_di5. " default - default implements interface and is tagged def

SM30, change standard width of Tablecontrol

$
0
0

One thing that always bothered me with the Table Maintenance Generator is that when we create a Dialog for a table with many fields the Table Control always show a width of 80 columns, even when the screen has space to show more content.

 

Wouldn't be great if we could harness this lost space?

 

Well, you can say, there is a simple fix for this. We can manually change the width of the Table Control, but the problem with this approach is that when the Generator is executed again (because a field was added to the table for example), the Table Control returns to the 80 columns layout.

 

With the solution proposed below, every time that the table is called in SM30, if the width is less than the desired the code kicks in and resizes the Table Control.

 

Solution:

 

Call the function to change it in the initialization event of the program using "Events" and pass to it the desired width of the Table Control. If the Table control and the enclosing canvas is less than the value passed the function change the width and re-generate the Dialog screen.

 

FUNCTION zsd_resize_table_ctrl.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(IV_TABLE) TYPE  STRING
*"     REFERENCE(IV_MAINT_FG) TYPE  STRING
*"     REFERENCE(IV_DYNPRO_NO) TYPE  CHAR4
*"     REFERENCE(IV_WIDTH) TYPE  I
*"----------------------------------------------------------------------  CHECK iv_width <= 255.  DATA:    BEGIN OF gs_dynpro_descr,      prog   TYPE progname,      dynpro TYPE char4,    END OF gs_dynpro_descr.  DATA:    lv_fnam TYPE d021s-fnam,    h TYPE d020s,    ls_f TYPE d021s,    f TYPE d021s OCCURS 0 WITH HEADER LINE,    e TYPE d022s OCCURS 0 WITH HEADER LINE,    m TYPE d023s OCCURS 0 WITH HEADER LINE.  DATA:    m1 TYPE string,    l1 TYPE string,    w1 TYPE string.  CONCATENATE 'SAPL' iv_maint_fg INTO gs_dynpro_descr-prog.  gs_dynpro_descr-dynpro = iv_dynpro_no.  CONCATENATE 'TCTRL_' iv_table INTO lv_fnam.  IMPORT DYNPRO h f e m ID gs_dynpro_descr.  READ TABLE f INTO ls_f WITH KEY fnam = lv_fnam.  CHECK sy-subrc = 0.  CHECK h-noco < iv_width.  h-noco = iv_width.

* convert to hexa
  DATA: lv_crmt_ei_kb_id TYPE crmt_ei_kb_id.  lv_crmt_ei_kb_id = iv_width - 2.  CALL FUNCTION 'CRM_EI_KB_CONV_DEC_TO_HEX'    EXPORTING      iv_decimal = lv_crmt_ei_kb_id    IMPORTING      ev_hex     = lv_crmt_ei_kb_id.  CHECK NOT lv_crmt_ei_kb_id+30(2) IS INITIAL.  ls_f-leng = lv_crmt_ei_kb_id+30(2). " '9B'. " 155 em hexa  MODIFY f FROM ls_f INDEX sy-tabix TRANSPORTING leng.  CHECK sy-subrc = 0.  EXPORT DYNPRO h f e m ID gs_dynpro_descr.  GENERATE DYNPRO h f e m ID gs_dynpro_descr MESSAGE m1 LINE l1 WORD w1.

ENDFUNCTION.

 

In the Table Maintenance Generator select the menu below:

 

events.jpg

 

Add the event 19, "after initializing global variables, field symbols, etc." for events reference see http://help.sap.com/saphelp_nw70/helpdata/en/91/ca9f0ea9d111d1a5690000e82deaaa/content.htm

 

form.jpg

 

Call the function passing, the maintenance table, maintenance function group, dynpro number and desired width.

 

FORM check_and_resize_tablecontrol.  CALL FUNCTION 'ZSD_RESIZE_TABLE_CTRL'    EXPORTING      iv_table           = 'ZTABLE'      iv_maint_fg        = 'ZMAINT_FG'      iv_dynpro_no       = '1100'      iv_width           = 160.

ENDFORM.

 

And that's about it, see ya!

Mini SIZZLING Hot game in abap

$
0
0

My first post !

 

First press: 'Cred' button for adding 'credits', then chose the 'Bet' botton for betting value, then 'Spin'.

When you 'win' you can double the winning amount by pressing '<5' or  '>=5'.

 

Have fun!

 

sly.JPG

***************************************************************************************************************************************

REPORT  zMini_SIZZLING.
TABLES SSCRFIELDS.
TYPE-POOLS: icon.
DATA: w_num TYPE i.
data: credit(4) TYPE p DECIMALS 0,
       cred2 TYPE i,
       bet TYPE p DECIMALS 0.
data: a type i,
        CASTIG TYPE P DECIMALS 0,
        castig2 TYPE p DECIMALS 0,
       B TYPE I.

DATA: FLAG, count(10) type c ,
f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,
p1(2) type c,
p2(2) type c,
player(2) type c,
ch type c,
rand(2) TYPE c.


SELECTION-SCREEN BEGIN OF BLOCK b1                          "rad1
WITH FRAME TITLE text-002 ."no intervals.
PARAMETERS: Message1(10) TYPE c MODIF ID ABC,
             message(10) type c MODIF ID ABC,
             BETS(2) TYPE C MODIF ID ABC,
             wining(10) MODIF ID ABC.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN:
BEGIN OF LINE,
   PUSHBUTTON 2(10) BUTgame1 USER-COMMAND CLIgame1 MODIF ID sc1,
   PUSHBUTTON 14(10) BUTnet1 USER-COMMAND net MODIF ID sc1,
END OF LINE,
BEGIN OF LINE,
PUSHBUTTON 2(10) BUT1 USER-COMMAND CLI1 MODIF ID sc1,
PUSHBUTTON 12(10) but22 USER-COMMAND CLI2 MODIF ID sc2,
PUSHBUTTON 22(10) BUT3 USER-COMMAND CLI3 MODIF ID sc3,
PUSHBUTTON 32(10) BUT101 USER-COMMAND CLI3 MODIF ID sc3,
PUSHBUTTON 42(10) BUT102 USER-COMMAND CLI3 MODIF ID sc3,
PUSHBUTTON 67(10) BUTdub USER-COMMAND CLI000 MODIF ID sc3,
END OF LINE,
BEGIN OF LINE,
PUSHBUTTON 2(10) BUT4 USER-COMMAND CLI4 MODIF ID sc4,
PUSHBUTTON 12(10) BUT5 USER-COMMAND CLI5 MODIF ID sc5,
PUSHBUTTON 22(10) BUT6 USER-COMMAND CLI6 MODIF ID sc6,
PUSHBUTTON 32(10) BUT121 USER-COMMAND CLI3 MODIF ID sc3,
PUSHBUTTON 42(10) BUT122 USER-COMMAND CLI3 MODIF ID sc3,
END OF LINE,
BEGIN OF LINE,
PUSHBUTTON 2(10) BUT7 USER-COMMAND CLI7 MODIF ID sc7,
PUSHBUTTON 12(10) BUT8 USER-COMMAND CLI8 MODIF ID sc8,
PUSHBUTTON 22(10) BUT9 USER-COMMAND CLI9 MODIF ID sc9,
PUSHBUTTON 32(10) BUT131 USER-COMMAND CLI3 MODIF ID sc3,
PUSHBUTTON 42(10) BUT132 USER-COMMAND CLI3 MODIF ID sc3,


END OF LINE,
BEGIN of line,

END OF line,
BEGIN OF LINE,
   PUSHBUTTON 2(37) BUT10 USER-COMMAND CLI10 MODIF ID sc3,
   PUSHBUTTON 41(5) BUT11 USER-COMMAND CLI11 MODIF ID sc9,
   PUSHBUTTON 47(5) BUT12 USER-COMMAND CLI12 MODIF ID sc9,
   PUSHBUTTON 65(5) BUTmin USER-COMMAND CLI001 MODIF ID sc3,
   PUSHBUTTON 74(5) BUTmax USER-COMMAND CLI002 MODIF ID sc9,
end of line,

BEGIN of line,

END OF line.
SELECTION-SCREEN END OF BLOCK b1.                           "rad1.

form box_disable using ch.
   LOOP AT SCREEN.
     IF screen-group1 = ch.
       screen-input = '0'.
       MODIFY SCREEN.
     ENDIF.
   ENDLOOP.
endform. "box_disable

AT SELECTION-SCREEN OUTPUT.

LOOP AT SCREEN.
IF SCREEN-GROUP1 = 'ABC'.
SCREEN-INPUT = 0.
MODIFY SCREEN.
ENDIF.
ENDLOOP.

   if f1 = 1.
     perform box_disable using 'SC1'.
   endif.
   if f2 = 1.
     perform box_disable using 'SC2'.
   endif.
   if f3 = 1.
     perform box_disable using 'SC3'.
   endif.
   if f4 = 1.
     perform box_disable using 'SC4'.
   endif.
   if f5 = 1.
     perform box_disable using 'SC5'.
   endif.
   if f6 = 1.
     perform box_disable using 'SC6'.
   endif.
   if f7 = 1.
     perform box_disable using 'SC7'.
   endif.
   if f8 = 1.
     perform box_disable using 'SC8'.
   endif.
   if f9 = 1.
     perform box_disable using 'SC9'.
   endif.

AT SELECTION-SCREEN .


   CASE SSCRFIELDS.
     when 'CLIGAME1'.
       "SUBMIT Z_TEST_XO_1  VIA SELECTION-SCREEN AND RETURN.
CALL TRANSACTION 'ZF_GAME_2' .
       when 'NET'.
       SUBMIT ZF_HTML1  VIA SELECTION-SCREEN AND RETURN.

     when 'CLI000'.
       DATA: BROWSER_TYPE       LIKE TOLE-APP VALUE 'INTERNETEXPLORER.APPLICATION',

       LV_HELP_MODE        TYPE CHAR1,

       LV_WINDOW_NAME      TYPE SYDATAR.



CALL FUNCTION 'GET_WEBGUI_HELP_MODE'

      IMPORTING

           HELP_MODE = LV_HELP_MODE.

IF LV_HELP_MODE = 'X'.

   LV_WINDOW_NAME = 'SAPNet'.

ELSE.

   LV_WINDOW_NAME = SPACE.

ENDIF.


     CALL FUNCTION 'CALL_BROWSER'

      EXPORTING

           URL                    = 'http://www.youtube.com/watch?v=6dja9wIHPJo&feature=player_embedded#t=59s'

           BROWSER_TYPE           = BROWSER_TYPE

           WINDOW_NAME            = LV_WINDOW_NAME

      EXCEPTIONS

           FRONTEND_NOT_SUPPORTED = 1

           FRONTEND_ERROR         = 2

           PROG_NOT_FOUND         = 3

           NO_BATCH               = 4

           UNSPECIFIED_ERROR      = 5

           OTHERS                 = 6.

IF SY-SUBRC NE 0.

   WRITE:/ 'Browser not called.'.

ENDIF.



     WHEN 'CLI001'.
       castig2 = wining.
       IF A = 1.
         CALL FUNCTION 'ISB_RANDOM_CHAR' "
         EXPORTING
          length = 1                  " sy-tabix
           pattern ='1234567890'                   "
         IMPORTING
           ran_char = butDUB                 "
         EXCEPTIONS
           INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR
         IF BUTDUB < 5 .
           WINING = WINING * 2.
         ELSE.
           MESSAGE1 = 'You Lost'.
           WINING = 0.
           A = 0.
         ENDIF.
       ENDIF.
     WHEN 'CLI002'.
       IF A = 1.
         CALL FUNCTION 'ISB_RANDOM_CHAR' "
         EXPORTING
          length = 1                  " sy-tabix
           pattern ='1234567890'                   "
         IMPORTING
           ran_char = butDUB                 "
         EXCEPTIONS
           INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR
         IF BUTDUB >= 5 .
           WINING = WINING * 2.
         ELSE.
           WINING = 0.
           MESSAGE1 = 'You Lost'.
           A = 0.
         ENDIF.
       ENDIF.
     when 'CLI11'.
       credit = credit + 500.
       MESSAGE = credit.
      " PERFORM beting.
     when 'CLI12'.
       "PERFORM beting.
       IF BET < 50.
         BET = BET + 10.
       ELSE.
         BET = 10.
       ENDIF.
       BETS = BET.
     when 'CLI10'.
       IF credit < bet.
           bet = credit.
           bets = bet.
       ENDIF.
        butdub = 'Press?!'.
       count = 1.
       credit = credit - bet.
       IF wining <> 0 .
             wining = wining + bet.
       ENDIF.
       MESSAGE1 = ''.
       CREDIT = CREDIT + WINING.
       IF credit <= -10.
         PERFORM reset.
       else.
         MESSAGE = credit.

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but101                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but102                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but121                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR
         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but122                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but131                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but132                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but1                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but22                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but3                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but4                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but5                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but6                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but7                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but8                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         CALL FUNCTION 'ISB_RANDOM_CHAR' "
           EXPORTING
            length = 1                  " sy-tabix
             pattern ='1234712341234'                   "
           IMPORTING
             ran_char = but9                 "
           EXCEPTIONS
             INVALID_INPUT = 1           . "  ISB_RANDOM_CHAR

         " prima linie ****************
         IF but101 = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but101
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but101 = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but101
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but101 = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but101
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but101 = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but101
             EXCEPTIONS
               OTHERS = 0.
         elseif  but101 = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but101
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.


         IF but1  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but1
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but1  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but1
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but1  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but1
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but1  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but1
             EXCEPTIONS
               OTHERS = 0.
         elseif  but1  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but1
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         IF but3  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but3
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but3  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but3
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but3  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but3
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but3  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but3
             EXCEPTIONS
               OTHERS = 0.
         elseif  but3  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but3
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         IF but102  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but102
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but102  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but102
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but102  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but102
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but102  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but102
             EXCEPTIONS
               OTHERS = 0.
         elseif  but102  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but102
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         IF but22  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but22
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but22  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but22
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but22  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but22
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but22  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but22
             EXCEPTIONS
               OTHERS = 0.
         elseif  but22  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but22
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.
         "a doua linie ********************
         IF but121 = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but121
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but121 = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but121
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but121 = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but121
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but121 = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but121
             EXCEPTIONS
               OTHERS = 0.
         elseif  but121 = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but121
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.


         IF but4  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but4
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but4  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but4
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but4  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but4
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but4  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but4
             EXCEPTIONS
               OTHERS = 0.
         elseif  but4  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but4
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         IF but6  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but6
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but6  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but6
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but6  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but6
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but6  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but6
             EXCEPTIONS
               OTHERS = 0.
         elseif  but6  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but6
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         IF but122  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but122
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but122  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but122
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but122  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but122
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but122  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but122
             EXCEPTIONS
               OTHERS = 0.
         elseif  but122  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but122
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         IF but5  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but5
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but5  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but5
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but5  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but5
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but5  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but5
             EXCEPTIONS
               OTHERS = 0.
         elseif  but5  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but5
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         "a doua linie ********************
         IF but131 = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but131
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but131 = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but131
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but131 = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but131
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but131 = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but131
             EXCEPTIONS
               OTHERS = 0.
         elseif  but131 = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but131
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.


         IF but7  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but7
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but7  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but7
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but7  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but7
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but7  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but7
             EXCEPTIONS
               OTHERS = 0.
         elseif  but7  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but7
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         IF but9  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but9
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but9  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but9
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but9  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but9
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but9  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but9
             EXCEPTIONS
               OTHERS = 0.
         elseif  but9  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but9
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         IF but132  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but132
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but132  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but132
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but132  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but132
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but132  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but132
             EXCEPTIONS
               OTHERS = 0.
         elseif  but132  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but132
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         IF but8  = 1.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = icon_okay
               text   = '1'
               info   = '1'
             IMPORTING
               RESULT = but8
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but8  = 2.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_LOCKED
               text   = '2'
               info   = '2'
             IMPORTING
               RESULT = but8
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but8  = 3.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_GREEN_LIGHT
               text   = '3'
               info   = '3'
             IMPORTING
               RESULT = but8
             EXCEPTIONS
               OTHERS = 0.
         ELSEIF but8  = 4.
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_YELLOW_LIGHT
               text   = '4'
               info   = '4'
             IMPORTING
               RESULT = but8
             EXCEPTIONS
               OTHERS = 0.
         elseif  but8  = 7 .
           CALL FUNCTION 'ICON_CREATE'
             EXPORTING
               name   = ICON_RED_LIGHT
               text   = '7'
               info   = '7'
             IMPORTING
               RESULT = but8
             EXCEPTIONS
               OTHERS = 0.
         ENDIF.

         PERFORM wining.
       ENDIF.

   ENDCASE.

*&---------------------------------------------------------------------*
*&      Form  reset
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
form reset.
   wait up to 2 SECONDS.
   butgame1 = 'Jocul 2'.
   butnet1 = 'Net'.
   credit = 100.
   BUT1 = 'L'.
   but22 = 'E'.
   BUT3 = 'T'.
   BUT101 = ','.
   BUT102 = 'S'.
   BUT4 = 'P'.
   BUT5 = 'L'.
   BUT6 = 'A'.
   BUT121 = 'Y'.
   BUT122 = ' '.
   BUT7 = ' '.
   BUT8 = ' '.
   BUT9 = ' '.
   BUT131 = ' '.
   BUT132 = ' '.
   CALL FUNCTION 'ICON_CREATE'
     EXPORTING
       name   = icon_okay
       text   = 'Spin/Colect'
       info   = 'Click to Continue'
     IMPORTING
       RESULT = but10
     EXCEPTIONS
       OTHERS = 0.
   but11 = 'Cred'.

   but12 = 'Bet'.
   f1 = ' '.
   f2 =' '.
   f3 = ' '.
   f4 =' '.
   f5 = ' '.
   f6 =' '.
   f7 = ' '.
   f8 =' '.
   f9 = ' '.
   Message = 'New Game'.
** Score = ' '.
   count = 0.

endform. "reset

initialization.
   count = 0.
   butgame1 = 'Jocul 2'.
   butnet1 = 'Net'.
   BUT1 = p1.
   but22 = p1.
   BUT3 = p1.
   BUT4 = p1.
   BUT5 = p1.
   BUT6 = p1.
   BUT7 = p1.
   BUT8 = p1.
   BUT9 = p1.
   BUT101 = p1.
   BUT102 = p1.
   BUT121 = p1.
   BUT122 = p1.
   BUT131 = p1.
   BUT132 = p1.
   but11 = 'Cred'.
   but12 = 'Bet'.


   CALL FUNCTION 'ICON_CREATE'
     EXPORTING
       name   = icon_okay
       text   = 'Spin/Colect'
       info   = 'Click to Continue'
     IMPORTING
       RESULT = but10
     EXCEPTIONS
       OTHERS = 0.

   cALL FUNCTION 'MOVE_CHAR_TO_NUM'
     EXPORTING
       CHR             = but11
     IMPORTING
       NUM             = credit
     EXCEPTIONS
       CONVT_NO_NUMBER = 1
       CONVT_OVERFLOW  = 2
       OTHERS          = 3.
   IF SY-SUBRC <> 0.
   ENDIF.
   cALL FUNCTION 'MOVE_CHAR_TO_NUM'
     EXPORTING
       CHR             = but12
     IMPORTING
       NUM             = bet
     EXCEPTIONS
       CONVT_NO_NUMBER = 1
       CONVT_OVERFLOW  = 2
       OTHERS          = 3.

   IF SY-SUBRC <> 0.
   ENDIF.

*&---------------------------------------------------------------------*
*&      Form  wining
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
form wining.

   a = 0.
   CASTIG = 0.
   B = 0.
   if but1 = but22 and but1 = but3 .
     IF but1 = but101.
       IF BUT1 = BUT102.
         IF BUT1 = '@0A\Q7@ 7' .
           CASTIG = 5 * ( CASTIG + 5 * BET ).
           B = 1.
         ELSE.
           CASTIG = 5 * ( CASTIG + 2 * BET ).
           B = 1.
         ENDIF.
       ENDIF.
       IF B = 0 AND BUT1 = '@0A\Q7@ 7' .
         CASTIG = 3 * ( CASTIG + 5 * BET ).
         B = 1.
       ELSEIF B = 0 AND BUT1 <> '@0A\Q7@ 7' .
         CASTIG = 3 * ( CASTIG + 2 * BET ).
         B = 1.
       ENDIF.
     ENDIF.
     IF B = 0 AND BUT1 = '@0A\Q7@ 7' .
       CASTIG = ( CASTIG + 5 * BET ).
       B = 1.
     ELSEIF B = 0 AND BUT1 <> '@0A\Q7@ 7' .
       CASTIG = ( CASTIG + 2 * BET ).
       B = 1.
     ENDIF.
     A = 1.
   ENDIF"PRIMA LINIE

   B = 0.
   if but4 = but5 and but4 = but6.
     IF but4 = but121.
       IF BUT4 = BUT122.
         IF BUT4 = '@0A\Q7@ 7' .
           CASTIG = 5 * ( CASTIG + 5 * BET ).
           B = 1.
         ELSE.
           CASTIG = 5 * ( CASTIG + 2 * BET ).
           B = 1.
         ENDIF.
       ENDIF.
       IF B = 0 AND BUT4 = '@0A\Q7@ 7' .
         CASTIG = 3 * ( CASTIG + 5 * BET ).
         B = 1.
       ELSEIF B = 0 AND BUT4 <> '@0A\Q7@ 7' .
         CASTIG = 3 * ( CASTIG + 2 * BET ).
         B = 1.
       ENDIF.
     ENDIF.
     IF B = 0 AND BUT4 = '@0A\Q7@ 7' .
       CASTIG = ( CASTIG + 5 * BET ).
       B = 1.
     ELSEIF B = 0 AND BUT4 <> '@0A\Q7@ 7' .
       CASTIG = ( CASTIG + 2 * BET ).
       B = 1.
     ENDIF.
     A = 1.
   ENDIF. "LINIE MIJLOC

   B = 0.
   if but7 = but8 and but7 = but9.
     IF but7 = but131.
       IF BUT7 = BUT132.
         IF BUT7 = '@0A\Q7@ 7' .
           CASTIG = 5 * ( CASTIG + 5 * BET ).
           B = 1.
         ELSE.
           CASTIG = 5 * ( CASTIG + 2 * BET ).
           B = 1.
         ENDIF.
       ENDIF.
       IF B = 0 AND BUT7 = '@0A\Q7@ 7' .
         CASTIG = 3 * ( CASTIG + 5 * BET ).
         B = 1.
       ELSEIF B = 0 AND BUT7 <> '@0A\Q7@ 7' .
         CASTIG = 3 * ( CASTIG + 2 * BET ).
         B = 1.
       ENDIF.
     ENDIF.
     IF B = 0 AND BUT7 = '@0A\Q7@ 7' .
       CASTIG = ( CASTIG + 5 * BET ).
       B = 1.
     ELSEIF B = 0 AND BUT7 <> '@0A\Q7@ 7' .
       CASTIG = ( CASTIG + 2 * BET ).
       B = 1.
     ENDIF.
     A = 1.
   ENDIF.                                                    "LINIE 3

   B = 0.
   if but7 = but5 and but7 = but3.
     IF but7 = but121.
       IF BUT7 = BUT132.
         IF BUT7 = '@0A\Q7@ 7' .
           CASTIG = 5 * ( CASTIG + 5 * BET ).
           B = 1.
         ELSE.
           CASTIG = 5 * ( CASTIG + 2 * BET ).
           B = 1.
         ENDIF.
       ENDIF.
       IF B = 0 AND BUT7 = '@0A\Q7@ 7' .
         CASTIG = 3 * ( CASTIG + 5 * BET ).
         B = 1.
       ELSEIF B = 0 AND BUT7 <> '@0A\Q7@ 7' .
         CASTIG = 3 * ( CASTIG + 2 * BET ).
         B = 1.
       ENDIF.
     ENDIF.
     IF B = 0 AND BUT7 = '@0A\Q7@ 7' .
       CASTIG = ( CASTIG + 5 * BET ).
       B = 1.
     ELSEIF B = 0 AND BUT7 <> '@0A\Q7@ 7' .
       CASTIG = ( CASTIG + 2 * BET ).
       B = 1.
     ENDIF.
     A = 1.
   ENDIF.                                                    "DIAG 2

   B = 0.
   if but1 = but5 and but1 = but9.                           "DIAG 1
     IF but1 = but121.
       IF BUT1 = BUT102.
         IF BUT1 = '@0A\Q7@ 7' .
           CASTIG = 5 * ( CASTIG + 5 * BET ).
           B = 1.
         ELSE.
           CASTIG = 5 * ( CASTIG + 2 * BET ).
           B = 1.
         ENDIF.
       ENDIF.
       IF B = 0 AND BUT1 = '@0A\Q7@ 7' .
         CASTIG = 3 * ( CASTIG + 5 * BET ).
         B = 1.
       ELSEIF B = 0 AND BUT1 <> '@0A\Q7@ 7' .
         CASTIG = 3 * ( CASTIG + 2 * BET ).
         B = 1.
       ENDIF.
     ENDIF.
     IF B = 0 AND BUT1 = '@0A\Q7@ 7' .
       CASTIG = ( CASTIG + 5 * BET ).
       B = 1.
     ELSEIF B = 0 AND BUT1 <> '@0A\Q7@ 7' .
       CASTIG = ( CASTIG + 2 * BET ).
       B = 1.
     ENDIF.
     A = 1.
   ENDIF.                                                    "LINIE 3

   IF a = 1.
     MESSAGE1 = 'You win '.
      butdub = 'Double?!'.
   else.
     MESSAGE1 = ''.
   ENDIF.
   WINING = CASTIG.
   BUTMIN = '<5'.
   BUTMAX = '>=5'.

endform. "check_x_win
*&---------------------------------------------------------------------*
*&      Form  BETING
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM BETING .


DATA: it_vbscript LIKE STANDARD TABLE OF soli WITH HEADER LINE,
       v_vbsfile LIKE rlgrap-filename.

*-----------------------------------------------------------------------
*  This code creates the vbScript to play sound ringin.wav
*-----------------------------------------------------------------------
APPEND: 'strSoundFile = "C:\WINDOWS\Media\notify.wav"' TO it_vbscript,
         'Set objShell = CreateObject("Wscript.Shell")' TO it_vbscript,
         'strCommand = "sndrec32 /play /close " & chr(34) & strSoundFile & chr(34)' TO it_vbscript,
         'objShell.Run strCommand, 0, True' TO it_vbscript.

*-----------------------------------------------------------------------
*  Generated Script file must be downloaded into the TEMP folder of
*  the Windows environment
*-----------------------------------------------------------------------
CALL FUNCTION 'WS_QUERY'
   EXPORTING
     environment    = 'TEMP'
     query          = 'EN'
   IMPORTING
     return         = v_vbsfile
   EXCEPTIONS
     inv_query      = 1
     no_batch       = 2
     frontend_error = 3
     OTHERS         = 4.

IF sy-subrc <> 0.

   MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

ELSE.

   CONCATENATE v_vbsfile '\my_script.vbs' INTO v_vbsfile.

*-----------------------------------------------------------------------
*   Script file is downloaded
*-----------------------------------------------------------------------
   CALL FUNCTION 'WS_DOWNLOAD'
     EXPORTING
       filename            = v_vbsfile
       filetype            = 'DAT'
       mode                = 'S'
     TABLES
       data_tab            = it_vbscript
     EXCEPTIONS
       file_open_error     = 1
       file_write_error    = 2
       invalid_filesize    = 3
       invalid_table_width = 4
       invalid_type        = 5
       no_batch            = 6
       unknown_error       = 7
       OTHERS              = 8.

   IF sy-subrc <> 0.

     MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

   ELSE.

*-----------------------------------------------------------------------
*  The Script file is executed
*-----------------------------------------------------------------------
     CALL FUNCTION 'WS_EXECUTE'
       EXPORTING
         commandline    = v_vbsfile
         program        = 'WSCRIPT.EXE'
       EXCEPTIONS
         frontend_error = 1
         no_batch       = 2
         prog_not_found = 3
         illegal_option = 4
         OTHERS         = 5.

     IF sy-subrc <> 0.

       MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

     ENDIF.

   ENDIF.

ENDIF.

ENDFORM.                    " BETING

********************************************************************************************************************************************************************

Getting started: ABAP-HR/HCM using PNP Logical databases

$
0
0

Logical databases is a differentiating factor in ABAP-HR since it is used extensively here. These logical databases are special ABAP programs that provide fundamental functionality required for reading and processing data related to HR.


SAP HR is divided into different sub-modules and most widely used of these sub-modules are Personnel Administration and Organizational Management. We have PNP and PNPCE logical database for Personnel Administration and PCH logical database for Organizational Management.


I will be covering the programming basics for using PNP (Personnel Administration) logical databases.


PNP for Personnel Administration– This logical database provides standard selection screen based on HR report category that is selected while creation. The data is selected based on the selection made on the selection screen. It also checks if the user who has started the report has the necessary rights/authorization required to read/process the data.


By default there are some report categories while having a pre-defined set of selection screen elements. But we can create our new HR report category to define custom selection screen elements. We can also add our custom selection screen elements in addition to the standard selection screen elements which exist in a pre-defined HR report category.


Sample structure of basic ABAP-HR report program


REPORT zreport.

 

INFOTYPES: 0001.       “This is the info type declaration area

 

TABLES: pernr.         “Key fields for Personnel Admin infotypes

 

 

START-OF-SELECTION.

GET PERNR.             “Get PERNR gets all data related to a PERNR

 

PROVIDE * FROM P0001 BETWEEN PN-BEGDA AND PN-ENDDA.

 

WRITE:/ P0001-PERNR,

        P0001-STELL,

        P0001-BEGDA.

 

ENDPROVIDE.

 

 

Infotypes are basically used to group related together. They provide information and store data for specific time periods. In the above sample program the INFOTYPE statement declares an internal table which is populated at the GET PERNR event.

For example if we have

INFOTYPE: 0001.

This instruction creates an internal table with structure p0001 and which is filled at the GET PERNR event. We also add MODE N to this instruction.

INFOTYPE: 0001 MODE N.

The addition of MODE N restricts data from filling into the internal table at GET PERNR.

 

GET PERNR statement is basically an event which triggers the data read operation into respective infotypes which have declared by using the INFOTYPES statement for each PERNR (Personnel Number) that satisfies the selection criteria.


Program Flow for GET PERNR event.

1.jpg

 

 

The flow of this program is completely dependent on the GET PERNR statement. It acts as a loop and processes all data related to each PERNR one by one. In the above example following sequence of steps occur:

  1. All data belonging to PERNR = 00009001 (example) is read into the internal table p0001 for the date range specified in the selection screen.
  2. All the statements below are executed and data related to above PERNR only exists in the internal tables which were defined at the infotype statement.
  3. After all the statements have been executed the program control goes back to GET PERNR statement, refreshes all the internal tables (like p0001) and reads new data related to the next PERNR = 00009002 into the respective internal tables.
  4. This process continues till all the valid PERNR are processed.

 

While each PERNR is processed we may need to process individual infotype depending on some constraints. A PROVIDE-ENDPROVIDE loop is used to evaluate individual infotypes.

For example:


PROVIDE * FROM p0001

                   BETWEEN pn-begda AND pn-endda.


* ABAP statements to process data for infotype 0001


ENDPROVIDE.

Viewing all 943 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>