Skip to Content
0

Call Method from a ABAP Program

Nov 16, 2016 at 12:45 PM

475

avatar image

Hi all,

I wrote two programs.

Program 1

REPORT ztm_prog1.
TABLES: scarr.


SELECTION-SCREEN BEGIN OF BLOCK 001 WITH FRAME TITLE text-001.
SELECT-OPTIONS: carrid FOR scarr-carrid.
SELECTION-SCREEN END OF BLOCK 001.

CLASS program DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS main.
    CLASS-METHODS initialization.
  PRIVATE SECTION.


ENDCLASS.
CLASS program IMPLEMENTATION.
  METHOD main.


  ENDMETHOD.
  METHOD initialization.
    CLEAR: carrid.
    carrid = VALUE #( low = 'LH' option = 'EQ' sign = 'I' ) .
    APPEND carrid TO carrid.
  ENDMETHOD.
ENDCLASS.


INITIALIZATION.
  program=>initialization( ).


START-OF-SELECTION.
  program=>main( ).

Program 2

REPORT ztm_prog2.


**** Call the method from Program 1
(ztm_prog1)program=>main( ). "How is the syntax ????

How can i call the static method main from program ztm_prog1?

10 |10000 characters needed characters left characters exceeded
* Please Login or Register to Answer, Follow or Comment.

5 Answers

Horst Keller
Nov 16, 2016 at 01:09 PM
4

You shouldn't do that but you can by using absolute type names.

Share
10 |10000 characters needed characters left characters exceeded
Sandra Rossi Nov 17, 2016 at 04:59 AM
3

You shouldn't code like that (as already told by the 3 other people)

Show 4 Share
10 |10000 characters needed characters left characters exceeded

Generally, you shouldn't program a class with only static methods either.

0

Really? In other OO languages (e.g. Java, C#) it is common to have utility classes which only provide static methods. What's the problem with it in ABAP? Should we preferably continue to use function groups?

0

Really. Hence the term "Generally". That doesn't mean that there aren't exceptions where it makes sense. E.g. utility classes. :-)

But bear in mind that over time, it might make sense to extract a bunch of related static methods, and refactor as a class modelling a particular object. E.g. you start off with a static method that checks for userid existence. Then you create another that returns a userid's validity. After a while, it makes sense to create a class to model userids. And that's just a part of keeping your code base clean and efficient.

However, these extracted classes should not be full of static methods. In the past, I've gone down that route, and then when I've needed to specialise, I can't subclass - so I have to refactor, and retest. My experience is that if I make them instance methods to start with, I save a lot of time and effort later in the game.

1

I think we fully agree ... in my comment i basically meant real utility classes with self-contained and independent static methods.

1
Raghu Govindarajan Nov 16, 2016 at 01:18 PM
2

If you are going to reuse those methods, all you have to do is move it into its own "real" class - that way both the original program and any other program can access the code the way they are supposed to.

A short cut to make this simple (if you have the correct version of ABAP backend) is that in the Source-Code Based mode in SE24, you should be able to just cut and paste the entire class in there and just change the name of the class in the source code.


Show 7 Share
10 |10000 characters needed characters left characters exceeded

I agree. It was annoying when people called subroutines this way, but with the methods there should be no reason to do that, especially with two Z programs. It's just bad design.

1

Just thinking about this again from a pointy-haired-boss (Dilbert reference for those who don't know) point of view. They feel threatened by any changes to existing code. So, I can kind of see where the boss will not allow changes to ZTM_PROG1 above. If you follow the boss man and move a copy to the common location, you have two sets of code. I have two suggestions for this...

1) Add a comment in big bold letters to ZTM_PROG1 (I am sure the boss man will allow comments, right?) that if any changes need to be made to the methods, start by pointing to the common code in the Z_MY_CLASS_TM. That will be a good excuse for deprecating the non-common routines when changes are required.

Don't make any actual code changes to keep the boss man happy. For ZTM_PROG2, point it to a common class Z_MY_CLASS_TM and do it the right way. This way when ZTM_PROG3 comes along, you have good common code for that too.

2) Simpler solution - but harder to execute - fire the pointy-haired-boss :)

0

Raghu, OP starts with "I wrote two programs". So there should be no pointy-haired boss telling OP how to do their job.

1

OP doesn't state timeline of the first program written, it could already be in production. Either way OPer was not thinking ahead that the wonderful code in program 1 could be reused - in that I totally agree with you about OP needing to do their job!

2

Just to add to what Raghu has already mentioned.

From SE24, you can easily import the local classes to global classes using:

Menu > Object Type > Import > Local classes in Program

BR,

Suhas

3

Even better! I couldn't find an equivalent in the ADT environment though.

0

I don't think one would need such an import function in ADT, where everything is source code based.

Just a simple copy-paste would suffice!

2
Jacques Nomssi Nov 19, 2016 at 11:01 AM
-1

Hello Thomas,

note Horst's proposal does not trigger the INITIALIZATION event:

CALL METHOD ('\PROGRAM=ZTM_PROG1\CLASS=PROGRAM')=>('MAIN').

Further options

  1. extract the local class logic into a separate include and use it in both programs
  2. the simplest thing that could possibly work: SUBMIT
SUBMIT ZTM_PROG1 WITH carrid = '?whatever?' AND RETURN.

JNN

Show 3 Share
10 |10000 characters needed characters left characters exceeded

1) Initialization in a class is by using a constructor, you don't even have to explicitly call it

2) Why put it in an include when you can just make a class out of it? Includes can not be independently tested, classes can be - just one of many advantages of a class...

3) Submit will run the entire program 1. All the poster wanted to do was explicitly call a routine

0

Thomas' class has no class-constructor. Calling the main( ) method directly yields a program context where the CARRID select-option is not initialized.
OTOH starting the report via SUBMIT first triggers the INITIALIZATION event that explicitly invokes the initialization( ) method, then executes the main( ) method. Consider this difference in the system behavior while evaluating alternatives.

An include can contain one (or more) local classes with their corresponding ABAP Unit test classes, so I think a discussion on my proposal to extract the class logic to an include should be about global against local classes (cf. public vs published).

JNN

0
Thomas' class has no class-constructor. 

Yes, and I am suggesting that he do change the initialization to a constructor so that the common initial code does not have to be explicitly called.

starting the report via SUBMIT 

You still haven't considered if that is really an option - what if program_1 changes system data that is not wanted at the moment, or is part of a workflow, or worse still sends out a end user document or customer facing document? Would you put in checks in program 1 to prevent that from happening?

about global against local classes (cf. public vs published). 

The author is talking about code ownership and formalities around it, not about the programming mechanisms.

0
Janakiram P Nov 17, 2016 at 04:59 PM
-4

As others suggested in this thread, it is not recommended to code this way.

But if you do not have any workaround( in cases like fixing other's code and cannot create a separate class etc), in ZTM_PROG1 have the PROGRAM=>MAIN() in a subroutine for e.g. PERFORM call_method and call this subroutine from ZTM_PROG2.

Show 1 Share
10 |10000 characters needed characters left characters exceeded

It's kind of not recommended to code this way either...

3