Quantcast
Channel: ABAP Development
Viewing all 948 articles
Browse latest View live

ABAP Dump Texts - Quick and Dirty

$
0
0

Matthew Billingham has written a helpful blog about ABAP dumps.

 

From my point of view a lot of helpful information is already contained in the short dump texts.

 

You might be interested to see these texts without having to raise the exception.

 

The following - quick and dirty - program can be used as a starting point.

 

Simply enter the dump id, e.g. COMPUTE_INT_ZERODIVIDE or TIME_OUT, in the selection screen and see the short dump text.

 

Kind of poor man's ST22.

 

No guarantee that it works in all cases. I tested some. Feel free to report errors or to improve that little hack.


REPORT ...

PARAMETERS errid TYPE snapt-errid.


CLASS write_dump DEFINITION.

  PUBLIC SECTION.
    CLASS-METHODS main.
  PRIVATE SECTION.
    CLASS-METHODS write_section
      IMPORTING VALUE(errid) LIKE errid
                section      TYPE snapt-ttype.
ENDCLASS.

CLASS write_dump IMPLEMENTATION.
  METHOD main.
    WRITE / errid COLOR COL_HEADING.
    SKIP.
    WRITE / 'What happened?' COLOR COL_HEADING.
    write_section( errid = errid
                   section  = 'W' ).
    SKIP.
    WRITE / 'What can I do?' COLOR COL_HEADING.
    write_section( errid = errid
                   section  = 'T' ).
    SKIP.
    WRITE / 'Error analysis' COLOR COL_HEADING.
    write_section( errid = errid
                   section  = 'U' ).
    SKIP.
    WRITE / 'Hints for Error handling' COLOR COL_HEADING.
    write_section( errid = errid
                   section  = 'H' ).
    SKIP.
    WRITE / 'Internal notes' COLOR COL_HEADING.
    write_section( errid = errid
                   section  = 'I' ).
    SKIP.
  ENDMETHOD.
  METHOD write_section.
    DATA tline   TYPE snapt-tline.
    DATA sect    TYPE snapt-ttype.
    SELECT tline ttype
           FROM snapt INTO (tline,sect)
           WHERE langu = sy-langu AND
                 errid = errid AND
                 ttype = section
                 ORDER BY seqno.
      IF strlen( tline ) >= 8 AND
         tline(8) = '&INCLUDE'.
        REPLACE '&INCLUDE' IN tline WITH ``.
        CONDENSE tline.
        errid = tline.
        write_section( errid = errid
                       section = sect ).
      ELSE.
        WRITE / tline.
      ENDIF.
    ENDSELECT.
  ENDMETHOD.
ENDCLASS.

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


Project Object - The best Excel (xls, xlsx, csv) file reader around?

$
0
0

Dear community,

 

I believe we have all been there. We want to read an excel file with some data in a table, and each time we look around for an example (or for the last report where we needed this), and each time we are faced with the same tedious tasks, which include but are not limited to:

  • You need to create the dialog to the user and limit it to the extension that you are able to read, making it very limited
  • You need to create a char like structure because the excel data will be imported in external format.
  • You need to take care of the conversion of each field (unless if it's just text), and many times you make assumptions in this conversion that are not always true (like the decimal separator, the date format...)

 

Now, what if it was possible to have this all done for you automatically??

 

Sounds like a dream? Well, now it's reality.

 

You can find it here:

Project Object - File Reader

 

Please check the Readme file for installation instructions.

 

Sounds interesting, how does it work?

 

Well, I'm glad you ask. This file reader uses the abap runtime type description functionalities extensively.

 

All you need to do is call the READ_FILE method of the class and provide it with the internal table where you want the data to be imported to. If you want to skip the dialog prompting for a file, you can use the importing parameter for the file path. There's also the classic optional "skip first line" parameter, if the user insists on uploading the file with the header line.

 

The "reader" is split into the next steps:

  1. Create a char like table automatically from the provided internal table. All fields will be type char with a length of 50 characters. If for some reason this is not sufficient for you, I have put a BAdI in place for you to override this.
  2. The "reader" will get the extension from the file path provided and will call the BAdI implementation for the respective extension. At the moment there are implementations for extensions CSV, XLS and XLSX. Please keep in mind that to read XLSX files you'll need to install abap2xlsx. More info on that here abap2xlsx
  3. The "reader" will convert the char like table into the internal format following the pattern: It will call a BAdI to allow the developer to override the default conversion per data element. If this BAdI is not implemented, it will check for a conversion routine. If the data element does not have a conversion routine, it will run a standard conversion algorithm (implemented in a BAdI) per data type.

 

 

This does a lot, but I need more, how can I enhance it?

 

I created the following BAdIs that allow you to enhance this file reader to best fit your needs:

  • Z_BD_FILE_READER_COL_TYPE - This BAdI allows you to override the data type used in the char like structure. Basically, if you need more than 50 characters, use this.
  • Z_BD_FILE_READER_CONV - This BAdI allows you to override the default conversion algorithm, in case you need to convert some data in a special way. You need to use filter F_ROLLNAME by providing the data element of the column you wish to override.
  • Z_BD_FILE_READER_EXECUTE - This BAdI allows you to create a new extension reader. As I mentioned, I have already implemented a reader for CSV, XLS and XLSX files. If you need another extension, you can implement this BAdI yourself. Feel free to share it with me if you want to contribute
  • Z_BD_FILE_READER_TYPE_CONV - If you don't override the default conversion, and if there's no SAP standard conversion routine, I have implemented a few conversion routines for the most "popular" types. These are text, date and numbers. The date conversion routine accepts pretty much every format (dd/mm/yyyy, yyyy/mm/dd, yyyymmdd...) and the number routine gets the format (decimal and thousands separator) from the user options, so as long as it matches the format in the file, it should work. If you encounter some fancy data type you'll have to implement the conversion yourself. If you feel like contributing, feel free to share

 

 

Some credit where credit is due

 

I'd like to thank Aaron Pennington for his help and inspiration, and I'd like to thank Christian Skoda also for his help and inspiration, and for being the installation manual tester

 

Of course, I'd like to thank as well the abap2xlsx team for sharing their xlsx reader.

 

 

Any comments or suggestions are appreciated as usual. If you have any questions, feel free to ask.

 

Best,

Bruno

Design - Dynamic Programming or Not...

$
0
0

Technical Design Time

 

So you are doing the technical design of a project.   OK - so the design and the coding have been done and you are supporting it.  (Me)   But pretend I helped design the "mess" I call dynamic programming.   Don't get me wrong, I love dynamic programming when used with some common sense.   But anyway...   Back to the story, YOU are doing a technical design for a project.

 

Requirement:

A screen is needed to display a table.   In the table there can be many records that relate back to one line.   You want to display the table in one line for editing, creating, and displaying.

 

Table

LineName of FieldDescription of FieldValue
1Crazy1Crazy field 1Yes
1Medication1Medication NeededTranquilizer
1Time_DangerousTime when dangerousWhile Programming
2Crazy1Crazy field 1No
3HappyWhen are happyNo computers
3Medication1Medication NeededNone

 

Display / Change / Create - After clicked on line 1

LineCrazy1Medication1Time_Dangerous
1YesTranquilizerWhile programming

 

Display/Change / Create - After clicked on line 2

LineCrazy Field 1
2No

 

OK Now lets make it a little harder - the fields for the lines are determined by different criteria.

LineJobNumber of yearsPeople interactionhours logged with people interactionColorAnimalName of Field
1Programmer3Crazy1
2ProgrammerNoCrazy1
3HorseCrazy1
4Independent wealthyHappy
5Yes10Medication1
6RedTime_dangerous

 

So it's an interesting requirement.    Let's pretend nothing in standard SAP will work for the requirement.   So what do you do?   What do you put in your technical spec?  How are you really going to program this beast?

 

Maybe the above isn't enough information.   So you get more and continue.

 

Dynamic programming is an option.   Probably a good one.   Use it with an ALV.   Ahhhhh... Now you see where I'm going with the dynamic programming.   But..   What about a Step-loop?   It's old, true.  And the display will look different - going down the page instead of across.  So which is the better choice?

 

Aha!  It's SAP ABAP we are talking about.   So the answer "It depends".   Yes!  Fist pump.  That is the answer.   I know it.

 

Questions to ask yourself

 

So step back - look at the mess and try to think about it.   Now step back again look at it again, and decide which will be the easiest to code.   Step back - yes look again, which is going to have the best performance.   Alright one more time - the last and most import to all of us that support your code - step back look again.   Which is going to be the easiest to support?  What skill levels are on staff?  What do they normally use?   What about the development team who will be developing the code?  What if it isn't you - can they do what you want?

 

So many questions and no good answer.

 

Decision Time:

 

So one more time - I'll move forward.

 

I decide to use dynamic programming and an ALV output.    I'm going to build a custom container to hold the code as I'm adding it via a screen exit.

Code Snipit

 

Here's some code:

 

code.JPG

 

I know not enough - but search on Dynamic programming.  You'll find a lot of examples.    This blog isn't meant to explain how to do it.  Also I know the requirements are not all detailed.  But hey we are developers, we know they aren't always well defined!   I like trying to read the back of the napkin for my functional requirements, it's always fun.

 

So now - answers to my questions.  Of course, my own answers.

Readability - Maintenance

 

Here's where it gets fun.   I'm a new program and have to maintain this.   Oh boy.   I wouldn't know where to start.   I'm an "older" programmer (Yes, I sure am) and I've never seen anything like this.  Either way the maintenance cost will go up.

 

Performance


Here it gets a little harder....   If I had used a step loop, I would have been querying and adding data screen by screen.   However, a step loop really didn't meet the requirement.   As a side note, if they used page up and down a lot - it really wouldn't have been a good performance save.   Do think about things like that if you are doing web programming, RF programming, etc.  Screen by screen or all at once?  And it would have depended on if I pulled all the data up front before moving from screen to screen.

 

Easiest?

 

Not always the best way to go.   It depends on your background.  For me, no this wasn't the easiest.

 

Should Dynamic programming been a technical requirement?

 

Do it sounds like step loop should have won, and dynamic programming should not have been used.   Well I would say the answers are interesting.  The one that would concern me would be the performance.

 

So did dynamic programming make sense?  YES!   Look at some different blogs.   I get to ride my soapbox a bit.  It's always fun.   It should have been used for many different reasons.  It is more flexible.   Once you learn it, it will be easy to maintain.  For what I'm using it for, it meets the requirement much better.   Performance is better.   But one of the best reasons - it's fun!   No not really, the best reason.   The best reason is it's going to expand the technical skills of anyone who has to maintain it.   Will it take longer for them to do?  Of course.  Will they complain?  Maybe.   But they will move forward a bit.

 

And yes, this is still a bit behind the times.  No web, no HANA... What can I say?  We aren't there yet.

 

So what do YOU think Dynamic or some other form of programming?  Would you have done something different?   Maybe even a newer technique I didn't think of.    Feel free to get on your soapbox.  I'd love to hear what you think.

Using UPL for doing just the needed rework

$
0
0

The Situation

In bigger and long-running projects you are faced more often than not with task to rework already existing coding. For example, the project used a specific version of a library and now it is time to upgrade this version to benefit from new features. Therefore the places in the coding where the library is used have to be found and adjusted.

 

In ABAP development, we see from time to time that some constructs are defined as obsolete. While there is in most cases no need to rework the code that makes use of these constructs as backward compatibility is done to the max in the ABAP stack (even to a point where it starts to get painful...), one might get rid of these obsolete coding for different reasons like

  • being state of the art
  • using it as a good "excuse" for doing additional refactoring work in the surroundings
  • just for feeling better not to rely on obsolete and possibly not supported features

 

But what to do if your project is a very long-running one and the amount of coding that would need a rework is really huge (say: above one million lines of code)? Wouldn't it be nice to first concentrate on that parts that are actually used daily in your productive system? If this is the case I probably have a little hint for you.

 

The Example

Let me give you an example that I had to deal with recently: We just upgraded one of our main ABAP systems from 7.01 to 7.40 SP7. A giant step forward and it went ok, except for one little problem. It seemed that using an old construct that was marked as deprecated years ago lead the using programs to dump when used heavyly in parallel (after some weeks it turned out that it was "just" a small bug in the ABAP kernel, but this is another story...).

As I searched for this construct in the code base of our 15 year old application with over 10 Mio. lines of code using a Code Inspector test, I found round about 400 places. Adjusting all of these places seemed to be a little bit too much even for a boring and rainy Friday afternoon, so I thought about how to strip this set down to reduce my work. Always remember: A good developer is a lazy one.

 

Within a mailing thread with Boris Gebhardt concerning the Code Inspector tests for HANA readiness he gave me the hint to use one of the many, but not so well-known object collectors to reduce the set of development objects to scan. A good advice for my task, as one of these object collectors was just the one I was searching for! But it needed a little bit of support from another tool.

 

Introducing UPL

Recently, we activated the Usage and Procedure Logging (UPL) on our productiv system to know about the used and the not used development objects. There is a nice document about Usage Procedure Logging (UPL) from Ashishkumar Banker that explains what UPL is and how it can be used. The link for an official how-to guide to UPL can also be found in Getting started with Usage and Procedure Logging (UPL) by Shuge Guo and Bjoern Panter. The official guide clearly explains the benefits of UPL compared to other monitoring tools like ST03, ABAP Coverage Analyzer and others. One of these benefits is that you get nearly no performance penalty from activating it, so you can safely do so even in productive systems to monitor the real stuff that is going on.

While UPL is well integrated into Solution Manager's Custom Code Lifecycle Management for managing obsolete and not used objects, there are also use cases when used on the monitored system in stand-alone mode. One of these use cases is to get a list of executable development objects that were actually used during the monitoring phase for further analysis.

 

Let's start the work!

If you have actived UPL according to the guides mentioned and let it do its magic for the planed amount of time (in our system it keeps a history of 31 days), you can start to harvest the results. Just start the report /SDF/SHOW_UPL and just the parameters to your needs. For example, I was interested in our own code so I narrowed the results to custom packages ("Z*").

 

UPL_EXport_to_CI.jpg

Marked red in the screen shot you find the parameter that will return the found results in a format that can be used with Code Inspector and one of its object colletors.

After some seconds, you will get a file that contains all the used objects in the following format:

 

UPL_Export_File.jpg

As you can see it is simply a tab-separated list of the object type and the name, similar to the TADIR table.

Important to notice here: The export will always return the surrounding objects in cases of methods, From routines and function modules. The UPL records down to this level of granularity and could be more specific, but the current version of the object collector expects the list in exactly this format.

 

What does this mean? For the presented use case it will result in some "false positives" as the Code Inspector will scan a whole class and not perhaps just the few methods that were actually executed. This is not correct from an academic point of view but for most use cases, the reduction of needed work will probably be good enough. And it is perhaps another argument against monster classes with too much responsibilities. :-)

For my use case I tried to check how this would affect my results. Therefore I used my free SAP Lumira account at https://cloud.saplumira.com to do a bit of analysis of the executed objects. As you can see in the diagram below, the top 25 packages are used very similar throughout a week and this also holds true for the top 10 development objects.

LumiraFun2.jpg

When I analyzed the data set a bit further I found out that in most cases surrounding objects are used to nearly 80% of their sub parts. So for me it was acceptable to look at the surrounding objects instead of the fine level of methods and single function modules.

 

Ok, now we switch to the Code Inspector. With the list from UPL we can create an object set using the object collector.

SCI_Create_Object_Set.jpg

You will find the list of installed object collectors on the last tab of the main screen:

SCI_Open_OC_list.jpg

To actually see the list of object collectors, use the search help that is marked in the screen shot above and you will get a popup like this:

SCI_Choose_OC_File_Upload.jpg

As you can see, there are many interesting object collectors available but I won't go into details for all of them now. The object collector that is need is called "Objects form File Upload" and accepts a simple text file with the format mentioned above. When you select it you will be for the file and that's it. You have just created an object set containing the really used objects in your productive system!

 

From here, it is the normal work with Code Inspector to search for certain constructs or errors. Create a new inspection with a matching check variant and the just created object set. When working on the result list of the inspection run you will be sure to work on just the objects that used. Nice!

 

There is of course one thing to remember: There is no guarantee that the set of objects that was executed during a small period of time is correct for a whole year. Some objects might just be used once a year on special dates. Keep this in mind when using UPL data on the managed system for narrowing down the search. Again, form an academic point of view, this way of doing things is not 100% correct. If you need more certainty you should probably have a look into Custom Code Management in the SAP Solution Manager. For my task (and perhaps also for some of yours) it was ok to probably miss out one or two objects. So I traded speed and ease of execution for absolute correctness.

 

The Result

Using the described procedure I was able to cut down the amount of needed rework to a half. As I started there were over 400 objects on my list. After matching these objects with the list from UPL, only 200 objects were left to concentrate on. Not bad for about 10 minutes of work.

The rest of the original list can be patched on another day or even be ignored. This depends on the probability of being used again and what happens if the problem should occur.

 

Conclusion

This will lead me to the end of my blog. I hope you enjoyed the ride and you cloud get some inspiration on using SAP tools in cooperation the reduce the amount of tedious work. If you have any comments or questions, just feel free to do so. I am looking forward to your feedback!

FM to get SD Document Flow

$
0
0

I'm writing this post in order to help others who have difficulties finding the correct SD document flow by accessing directly to standard tables. SAP provides us with a function module called SD_DOCUMENT_FLOW_GET, it's very easy to use and fast enough to look for all the documents in the flow. To give you an example I'll use an Outbound delivery, but you can you any SD document such as Sales Orders, Invoices, etc:

 

1. Let's go to transaction SE37 and in parameter IV_DOCNUM enter the Outbound delivery number:

foto1.png

 

2. We get the list of the SD document flow for the Outbound delivery, for our example there are seven documents:

 

foto2.png

 

3. Let's open the table ET_DOCFLOW to see all documents:

 

foto3.png

 

4. The fields of these table are important:

 

DOCNUM: SD document number.

FOCUS:     Points the document from which the search began.

HLEVEL:    Hierarchy position on the document flow tree.

VBTYP_N: SD document category (type of document for DOCNUM field). In our example we have the following:

 

CategoryDescription
COrder
JDelivery
RGoods movement
MInvoice
8Shipment

 

You can check the complete list of categories by looking the VBTYP domain's values in transaction SE11:

 

foto4.png

 

And that's all we get the SD documents from the order up to the accounting document in FI. As an advice you should order the table by the fields ERDAT and ERZET in descending order to see the documents by the date they were created.

 

I hope this help you with your SD Abap developments.

Does ABAP Really Require Longer Procedures?

$
0
0

Note: I did originally publish in the following post in my company's blog on software quality. Since it might be interesting for many ABAP developers, I re-publish it here (slightly adopted).

 

My colleague once summarized the benefits of short methods in his blog post: These are easier to comprehend, do better document the code (by the method name), are better to reuse and simplify testing as well as debugging or profiling. As the examples were in Java, one may intend that this will work for modern languages—but not in general, and maybe not for a language like ABAP. In this post I’ll focus if short procedures (e.g., methods, function modules, or form routines) have the same relevance for ABAP or if longer procedures are to legitimate or can not be avoided.

 

As an upper limit for a sub-routine’s length the post suggested 40 lines of code or the number of lines visible at once in the editor window. Sometimes even 40 lines are considered as far too long. For example, Robert C. Martin stated in his well-known book Clean Code that even 20 lines are too long and preferred micro methods with only up to five lines. Even in Java and C# development, keeping methods that short is rarely seen in practice. However, from our experience when analyzing and auditing Java or C# projects we see that most Java or C# developers agree on the advantages of having methods fitting on a screen page. Of course we’ve seen Java / C# code with a high amount of very long methods, but usually the developers are aware that this is not like it should be.

 

The situation is quite different when we analyze ABAP code. Of course, also here developers agree that methods and procedures in general should not become too long—but procedures with some hundred lines are more often considered as acceptable and sometimes are even preferred over short procedures. Also the official ABAP programming guidelines recommend a maximum of 150 statements and SAP’s Code Inspector will issue a warning only above this threshold with its default configuration for the procedural metrics check (see image).

 

sci_proceduarl_metrics_config.png

SAP Code Inspector default configuration for procedural metrics

 

 

Since every statement should be placed on a single line, but may span several lines, a 100 or 150 statements long method will often be a few hundred lines long. Taking comments and empty lines into account, this number even increases.

 

So, does ABAP Require Longer Procedures?

 

Indeed, there are some reasons, that Java thresholds are not suitable for ABAP. One will note that many constructs require much more lines of code, if the code is reasonable formatted. For example, comparing a method call with three parameters in Java, e.g.

 

     result = calculateResult(x, y, z);

 

with the call to a similar function module in ABAP:

 

     CALL FUNCTION 'Z_CALCULATE_RESULT'

       EXPORTING

         iv_x = lv_x

         iv_y = lv_y

         iv_z = lv_z

       IMPORTING

         ev_result = lv_result.


Thus you need seven lines of ABAP code for one line of Java code. The same applies to a simple loop over a number range. In Java this are two lines (not counting the content of the loop)

 

     for (int i = getStart(); i <= getEnd(); i++) {

        // loop content

     }

 

but ABAP requires five lines (again, without the loop content):

 

     DATA lv_i TYPE i.

     lv_i = get_min( ).

     WHILE lv_i <= get_max( ).

       " loop content

       lv_i = lv_i + 1.

     ENDWHILE.

 

The latter example also shows, that variable declarations—which do not really increase the complexity—require an additional line. From these examples, one could argue that for ABAP the procedure length will be around three or four times compared to Java to achieve the same functionality.

 

 

Count Lines or Statements?

 

Especially when thinking about the many lines a simple function call requires in ABAP, developers often suggest to count statements instead of lines. Indeed, this would rate the function call of the first example like in Java, but still ABAP requires more statements in many cases as shown in the second example. Furthermore, consider statements like the following SELECT:

 

     SELECT * FROM zcqseexpobj AS z INTO TABLE deleted_objects

       WHERE z~export_config_id = me->export_meta_data-export_config_id

             AND z~object = 'PROG'

             AND (

                     NOT EXISTS (

                             SELECT * FROM tadir AS t

                               WHERE t~pgmid = 'R3TR'

                                     AND t~object = z~object

                                     AND t~obj_name = z~obj_name

                                     AND t~delflag <> 'X'

                     )

                     OR NOT EXISTS (

                             SELECT * FROM reposrc AS r

                               WHERE r~progname = z~obj_name

                                     AND r~r3state = 'A'

                     )

               ).

 

This is a single statement but lasts over 17 lines - and in my view it is at least as complex as 17 lines are and is not just one »simple« statement. The example is from our ABAP code extractor which we need to analyze the code—and I really would not like to have more than two of these in a single method, thus the 40 lines limit would be perfect here. As you see, statements can get very complex. That’s why we strongly prefer to count lines of code over number of statements (and it’s always clear what a line is, but not always what to count as statement). More complex procedure metrics aren’t helpful either, see e.g. Benjamin’s post on McCabe’s Cyclomatic Complexity.

 

 

Well, Let’s Count Lines—but What’s a Good Length Limit for ABAP then?

 

 

As we’ve pointed out, ABAP syntax often requires more lines in contrast to other programming languages, thus 40 lines might be a too hard limit, I agree. But 100 lines or more should be an exception if you want to keep your ABAP code maintainable. Even if you usually can express much more functionality in 40 lines of Java than in 100 lines of ABAP code. Yes, in general for Java I’d accept methods comprising more functionality than in ABAP. There are basically two reasons: First, if more lines are written, one has to read and understand more lines—thus influencing comprehensibility on its own. But the more crucial issue is the scope of local variables.

 

 

ABAP: There are No Block-Local Variables

 

In Java, C#, and most languages which support statement blocks, the scope of a variable defined inside a block is only from the declaration of the variable to the end of the block. For example, when defining a variable inside a loop, the variable is not accessible anymore after the loop block. This helps to lower the amount of variables which you have to consider at a certain position of your code and avoids misuse of already defined variables.

 

In ABAP, however, a local variable is visible from the line of its declaration till the very end of the procedure. Thus the amount of variables in your scope will always increase, even if the variable is needed only inside a specific IF, ELSE, WHILE, SELCET, or whatever block. One could reuse a variable later to store a semantically completely different value (maybe because someone is too lazy to spend an extra declaration, or one has defined a generic multiple purpose »helper« variable)—this really makes code hard to understand and is extremely error-prone. But even if variables are not misused, the number of variables to track alone has a decisive impact on how easy the code is to follow. That’s why we recommend ABAP procedures should regularly stay clearly below 100 lines.

 

 

Summary

 

The benefits of short procedures on comprehension, documentation, reuse, testing and profiling/debugging are independent from the used programming language. ABAP has indeed a more verbose syntax which justifies a higher threshold than 40 lines of code. Still we prefer to count lines, not statements since a single statement could be as complex as a single method. Since it is very important to keep the total number of declared local variables low in ABAP—as all are valid in the whole procedure—I’d recommend that for maintainable ABAP code it should be aimed to have procedures clearly shorter than 100 lines.

 

When we do quality analysis or quality control of an ABAP project, we apply usually a maximum length limit of 80 lines (or 60 lines when not counting blank and comment lines) to rate a procedure as green. For the vast majority of code, a procedure length of 80 (60) lines should be a reasonable limit. Of course, there will be always a few procedures for which it makes no sense to cut them into thus short parts, but these should remain an exception.

SAP User Tracking System - Part 4

$
0
0

Hi


It's another program, where i have use CL_GUI_TIMER class, and based on that displaying the User Login Information in different location.


In this program, at the starting a screen open with maps, which will contains the all user location information, those has been logged on to the system or still login.


The page is refresh after certain time slap, this page refresh information will store in ZGEOKEY table (point 3).

 

But that too only refresh, where any one of the user information change or any new user login to the system.


AT PBO event.


Creating the Object for the CL_GUI_HTML_VIEWER class and considering the whole screen as container.

Call the below Methods to display the Location Information.


a. GET_TODATS_USER.


    

 

 

Collecting all users’ information from the ZLOGIN Table, based on the Today/ current date and storing into the E_BNAME range table.

 

b. SET_MAP_REFRESH_TIME

 

     In this method creating an object of CL_GUI_TIMER class and fetching the Refresh Time information from      ZGEOKEY table based on the USER ID (I_BNAME)

 

    

 

 

     And setting a handle to refresh the Screen through TIMER_FINISH_EVENT method, which is event for the      CL_GUI_TIME.

 


   c. TIMER_FINISH_EVENT

This method trigger based on the refresh time of the CL_GUI_TIMER object.

Inside this Method again I call the GET_URL method,  and if found,  URL information, then only refreshing the URL information of the CL_GUI_HTML_VIEWER class.

 

  d.GET_URL

              

 

        This is the method to get the URL Information, which will display the Google Map with the Users Login Location Information. (Point 5).


Output:

Initially only single user login, so the output will display the below map.

         


After Sometime, i logged with SAP* user, but accessing the system in same location, so forcefully change the location information.

         


Map will refresh only, if any user will login.


Happy Learning

Praveer.       





SAP User Tracking System - Part 3

$
0
0

Hi


Now the final part to display the Outcomes.


5. Program to Display users Logged Information.


     Now display the Information in final output and check the created service is working fine or not.

  Now it’s show time.

    

       Create a Program with Select-Option (below image) and a blank screen.

    

     In start-of-selection event

 

     Generate Object for the CL_GUI_HTML_VIEWER.

 

      Call the below methods to display to generate the URL information based on the Entered User ID’s in input      field.


     a. GET_URL

              

         

In this method, I am passing the User ID, which is a range table.

Based on did query on ZLOGIN table and fetching the User Login Information.


Now, this is the method where I am storing the information in ZMAPLOC table, why?

It may be possible a user is accessing the system different places or same user id is used by different place by different users, so the location information could be more.



Created a Number Range Object ZURLID





Updating all information’s, like URL ID, City, User Name, latitude and longitude in ZMAPLOC table and creating the URL with URLID information.


If any information not found, then displaying an image from the MIME directory.



Call screen 9000.

 

In PBO of the Screen,

 

Call method SHOW_URL of the CL_GUI_HTML_VIEWER object.


1st time, it will ask User ID and Password of the SAP Login.

After Provide the Credentials,

              Final Output:


 

After select any of the marker a small info window will open to display User and Location Information (as display above image)

 

SAP User Tracking System - Part 4

 

Happy Learning..

Praveer.


SAP User Tracking System - Part 2

$
0
0

Hi


Still steps are waiting to follow and find the final output comes. We have to write code which contains google map environment to display Google Map. Now i continue with pending steps...


4. Created a Customized Service to Call the Google Map


     To display Google MAP, I have created a customized service in SICF T-Code to execute an URL from SAP ends. Below is screen, where ZGOOGLE_MAP is the service name.

    

     


     The customized service should be in


          SICF-->DEFAULT_HOST-->SAP-->BC-->


     It’s HTTP based service, find the more information below.

    

    


     Create a customized class and pass in Handler List Tab, here I have created ZCL_GOOGLE_MAP class.

    

    


     Inside the class, I have used IF_HTTP_EXTENSION interface and write the code inside the      IF_HTTP_EXTENSION~HANDLE_REQUEST Method.

    

    

    

    


     Find the Method in attachment; inside the method I have call below methods.

    

     a.GET_LOCATION

 

               IF_HTTP_EXTENSION~HANDLE_REQUEST called, when I pass the link in URL. I have maintained                one ID URL,

         

          http://iprv.com:8000/sap/bc/zgoogle_map?sap-client=000$$000216


          By the server->request->get_header_field( name = '~QUERY_STRING' ). system will return the                     "sap-client=000$$000216 information"

         

          where 000 is the client and 000216 is URL ID.

         

          Read the URL information, and Passing the into the GET_LOCATION method to get the all Information in           IT_LAT_LONG internal table.

         


     b. GET_GEO_KEY

This method I already explained under point 3, to get the GEO Key information based on the User ID.


    

     c. CREATE_JS_LOCATION_FOR_MAKER

               Aah now it’s came, this is the Final Part of the All Process, through this method; I am creating a HTML                page which contains the Java Script and Google map coding to Display the Google Map and Location                Information.


        


          Inside this method I have written the code to display the location and while clicking any of the Marker, a           small pop-up (info Window) will open, which will display the User ID and Location Name.

          And the all Information will return in E_JSCRPT parameter.

     

     d. CREATE_FINAL_HTML

          And this is the Final Method, through this I am creating a HTML page and passing the java script           information in-between.

         

         


         

          And final, passing html information in below code.

     

     server->response->set_cdata( data = lv_html ).


SAP User Tracking System - Part 3


Happy Learning..

Praveer.

SAP User Tracking System - Part 1

$
0
0

Hi


My Question is very simple; can we track user login information? Yes, one way is there, I think everybody knows the answer, but let me explain.


To activate any of the Exist, that’s trigger at the time of login.


Yes the same way I did, I Activate the SUSR0001 Exist. And write codes to store the Login Information of the User.


But here my point comes, from where user is accessing or accessed the System?



Yes, there it is, above a marker in MAP, Now my analysis comes here, I did some analysis and modified the login information while doing the storage process.


Here I have used an already created Web Service, to get the Public IP address of the Used System and location based information.


Below are the Steps which I have followed to store the Information and display the Google MAP with the Login location.


  1. Activate Exist to Store login information.
  2. Activate the Google Service for SAP,  though SAP used IE as default browser,
  3. Activate Google API MAP in Google
  4. Created a Customized Service to Call the Google Map
  5. Program to Display users Logged Information.
  6. Program, to see current login Information of User based on today date.


  1. Activate Exist to Store login information.

 

          As I have explained, we have to store the User Login Information, since SAP is not storing the 

          All Login information, you can check the current login information in USR41 Table,

          Once you log-off and re-login, the current login information will update into the same table.

          So I have to store the all Login Information in custom table, Below is the Table Information


 

In the above table, I am storing the all information which I need.

In attachment (UPDATE_LOGIN) Methods to update the Information into ZLOGIN table.


Inside the Method, I have used


                    http://ip-api.com/json


web service to get the Public IP and Location Information in JSON format.

Method in GET_WEB_SERVICE_INFO attachment, in this method, I am passing Web Service URL and getting the JSON format information in E_INFO parameter.




2.Activate the Google Service for SAP,  though SAP used IE as default browser,

 

     I have used CL_GUI_HTML_VIEWER class to display the Google map in SAP screen.

     When I have tried 1st time, the map itself not displaying and I did some analysis and found. SAP      opens IE (Internet Explorer) as default browser.

     I have put a thread in this forum and found the Answer. it's contains the all changes information to activate      the Google service in SAP.


     Note: All Changes has to do in Application Server Side.

 

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

    

 

3. Activate Google API MAP in Google


     To use Google MAP in coding, we require Google Service Key, Please find the below link to activate the Google API Key.

 

     https://developers.google.com/maps/documentation/javascript/tutorial


     Follow the all steps from the above link, and generate the API key.

     I have stored the API Key Information in customize Table and fetch the same through Class Method.

     Below is the table, where I am storing the Information.

    

    


     In this table, I am storing the MAP API key, Map Type and Map Refresh Time.


    


     Based on the user id, I am storing the information.

     Below are the Methods I am using to SET and GET the information from the ZGEOKEY table.

      

     a. SET_GEO_KEY

 

              

    

     b. GET_GEO_KEY

              

              


     Please find the SET_GEO_KEY and GET_GEO_KEY method code in attachment.


SAP User Tracking System - Part 2


Happy Learning..

Praveer.



HR_INFOTYPE_OPERATION : Synchronous Employee Data Update

$
0
0

Introduction:


Most often we come across requirement to update employee master data, with synchronously update / modify multiple info type in one transaction.


Intent of given document to brief about approach to update multiple info type by using standard functional module HR_INFOTYPE_OPERATION.


Overview:


To explain more, we’ll take following illustrating example:


Business needs to created new records automatically in info type 033 as and when records got changed or created for Organizational Assignment (info type 0001).


Thus during updating of info type 0001, simultaneously info type 033 three sub type new records should be created in background.


Trouble Area:


During such type of requirement  we need to give leverage on Dynamic Action i.e. SPRO->Personnel Management->Personnel Administration->Customizing Procedures->Dynamic Actions. But there is lot of challenges with Dynamic action esp. when we need to Create/Update / Delete record with certain validations or substitute some values where integration with legacy system involved.


From ABAP side we do face lot of challenges while using HR_INFOTYPE_OPERATION, primary one will be employee locking issue along with inconsistent commit transaction as internally given functional module called PA40 through means of BDC - Batch Data Communication.


Addition of info group will be another approach but it will involve manual intervention. Thus most of the user will discard that approach.


Implementation:


Step 1: As a first step, we’ll create / change in employee master data for Organizational Assignment i.e. 0001 Info Type through transaction code PA40.


Step 2:  With “SAVE” action of the above, Update task will be triggered .We’ll implement standard BADI HRPAD00INFTY, Method IN_UPDATE, which will be called during update task. As required, we’ll lock employee to create other info type data synchronously in background.


Afterwards,we’ll call our custom functional module ZHR_FM_UPDATE. So, all required business logic will be encapsulated in custom

functional module ZHR_FM_UPDATE.All import / export parameters can be custom adjusted as per requirement.


Step 3: In this functional module ZHR_FM_UPDATE, we’ll create new LUW, with unique identifier w.r.t Info type + Date + Time for background task.       

 

Step 4: As we need to trigger HR_INFOTYPE_OPERATION in new background task, we must to have RFC enable functional module. But

HR_INFOTYPE_OPERATION is not RFC enabled thus we need to create wrapper for the same.


Thus we’ll create new wrapper functional module ZHR_FM_UPDATE_LUW, containing below given flow logic to create info type data for 33 i.e. Statistics records will be created.


Good part we can have re-usability to implement any custom logic in case if needed before updating of records .

 

As needed, we can create multiple LUW (Task) to update different info type one after another.


Step 5: Last but not least, employee needs to be unlock through  BAPI_EMPLOYEE_DEUEUE and HR_PSBUFFER_INITIALIZE. Afterwards execution will be back to update info type 001 – Org. Assignment records. Thus in one transaction, multiple records created for given employee.

 

Hope document will be helpful to cater synchronous employee details update.

The case of cl_http_utility=>decode_x_base64

$
0
0

Hi,

 

Lately there was a thread of converting BASE 64 TO PDF .

 

I was intrigued so I decided to do some tests (We might get any kind of data this way) .

 

Using Java I generated a Base64 text file (this will be used as input ) .

screenshot_01.png

This is how the output file looks like (1,060,588 byte long string)

screenshot_02.png

Time for some abap code:

 

Program steps ( Y_R_EITAN_TEST_31_10 ) :

screenshot_01.png

 

- Using cl_gui_frontend_services=>gui_upload to upload the text file (C:\temp\An Easy Reference for ALV Grid Control.pdf.txt).

- Using cl_http_utility=>if_http_utility~decode_x_base64 to decode the data the output from this method is xstring .

- CALL METHOD cl_gui_frontend_services=>gui_download to write the xstring as PDF (C:\temp\An Easy Reference for ALV Grid Control.lcl.pdf) .

- Use OPEN DATASET BINARY MODE to write the xstring as PDF to a shared folder (\\server\<some shared folder>\An Easy Reference for ALV Grid Control.shr.pdf)

 

The new PDF files can be opened with no problems using adobe reader

 

Comparing the files using MD5 tell me that the file downloaded using cl_gui_frontend_services=>gui_download is not identical to the original !!!!

screenshot_02.png

 

So I used a binary editor to compare:

screenshot_04.png

There is some extra bytes in the new file .

 

This does not interfere in this case but might cause a problem with other file formats and it is annoying...(Any idea ???? )

 

This all for now.

 

regards.

 

Thanks to the sharp eyes of Tomas Buryanekthe problem with cl_gui_frontend_services=>gui_download was solved (My bug...)

 

We need to send to cl_gui_frontend_services=>gui_download the original file size (p_filsiz).

screenshot_01.png

Simple generic popup selection screen for quick input or output

$
0
0

Hola,

 

Today I'm going to share with you some tiny class that can save up much time when you develop something rapidly.

 

For those guys who accepts generic programming it will be a good present as well.

 

So with the help of the class CL_CI_QUERY_ATTRIBUTES we can raise a screen like this:

 

upload_2015-01-27_at_1.05.03_pm.png

with the code like this:

 

report ztest_generic_screen.
start-of-selection.  perform main.
form main.  data: lv_bukrs type bukrs,        " select-options: type range of.. (must be dictionary type)        lrg_werks type ckf_werks_table,        " select-options: table, separate values        lt_werks TYPE plants ,        " checkbox + radiobutton ( must be DDIC types )        lv_simulate type xfeld,        lv_mode_open type xfeld,        lv_mode_close type xfeld,        lv_language TYPE spras.  lv_language = sy-langu.  " Generic screen call  cl_ci_query_attributes=>generic(    exporting      " unique screen ID      p_name       = conv #( sy-repid )      " Screen title      p_title      = 'Generic screen for input'      " Screen fields      p_attributes = value #(        " parameter field       ( kind = 'S'         obligatory = abap_true         text = 'Company code'(001)         ref = ref #( lv_bukrs ) )       " select-option       ( kind = 'S'         text = 'Plant'(002)         ref = ref #( lrg_werks ) )       " selec-option no intervals       ( kind = 'T'         text = 'Additional plants'(008)         ref = ref #( lt_werks ) )       " Screen groupd       ( kind = 'G'         text = 'Mode'(006)         ref = ref #( SY-INDEX ) )       " radiobuttons       ( kind = 'R'         text = 'Open'(004)         button_group = 'MOD'         ref = ref #( lv_mode_open ) )       ( kind = 'R'         text = 'Close'(005)         button_group = 'MOD'         ref = ref #( lv_mode_close ) )       " checkbox field       ( kind = 'C'         text = 'Simulate'(003)         ref = ref #( lv_simulate ) )       " listbox field       ( kind = 'L'         text = 'Language'(007)         ref = ref #( lv_language ) )       )    " Table of Attribute Entries      p_display    = abap_false    " General Flag  ).
endform.

 

As you see we can use checkboxes, radiobuttons, listboxes, screen groups, obligatory option.

 

I don't pretend this class to be used in serious programs, as of course only screens provide all the necessary stuff.

 

But if we speak about some simple screen to be raised from the class - this is kind of a fast solution avoiding screen and GUI status creation.

 

Good Luck,

 

I hope you liked it!

 

Adios.

Code Review: Success factors

$
0
0

We often hear that code reviews are frustrating and waste of time. Really?? Or is the lack of adoption of a suitable, well-defined process that is the root cause of it appearing futile. Think again!!

 

There are many articles highlighting the importance of doing code reviews, listing out to-do and not-to-do instructions, as well as explaining different code review alternatives (automated, peer review etc.), hence I am not detailing those here.

 

Through this blog, I want to stimulate the thought and highlight the importance on "how" the "right" code review process tailored per your "organization structure and need" play a significant role in embracing the code review mind-set within the project team and stakeholders.

 

By "right" code review process, I mean it is accepted and easily integrated within your software development/release life cycle (SDLC). It shouldn't look disparate, additional step or hindrance.

 

To evolve to "right" and robust code review process, your first step is to ensure that the code reviews are encouraged and it happens. This is truly possible only if there is awareness on its importance and have buy-in from key stakeholders. It is not only the developers that drive it but sincere acceptance and encouragement from Project Managers, Business leads, Analysts and End-users that primarily contribute to its success.

 

I am part of SAP Development team and feel proud to say that in my current organization this process is thoughtfully customized, neatly defined and well-integrated with other phases of SDLC.

 

We have clearly written code review check-list, coding standards document that is easily accessible to stakeholders. These documents contain answers to FAQs, security related coding norms, tips/pointers to improve performance and also inputs to write code for easy maintainability and support globalization/reuse.

 

To effectively implement the code review process, we have a dedicated code review team which is an independent, unanimously recognized group that governs the process and the coding standards. It functions across modules and projects and owns accountability of code changes moving to production environment.

 

The code review process is also tightly integrated with the subsequent Change Control process (process that focuses on moving code changes to production) in SDLC. The change control mechanism checks for code review status and warns when a code that is not reviewed is proposed to move to Production. In such case, it alerts and triggers action points for stakeholders to take appropriate action.

 

I am highlighting key points that have worked well for us

 

Mind-set:

To develop this mind-set, project team is kept informed and educated via different forums(seminars, blogs, trainings and question hours) to have their buy-in and feedback. This has helped in evolving to "Right" process.

 

The Team:

Forming of "dedicated", "independent", "unbiased" group is key to its unanimous acceptance. The role and responsibility of the team is clearly defined and accepted. The team has a good mix of experienced professionals having wide-ranging technical understanding.

 

Documentation:

The content is simple, precise and easy to understand without missing out on the exceptions/specifics. It is easily available to all. Any updates to it and its communication are well governed.

 

Deep integration:

The process is thoughtfully tailored per our need and is well-integrated with other phases of Software Development Life Cycle (SDLC). Though an independent process, it is an integral part of SDLC.

 

With the above thoughts on the code review process. I open up for further discussion and invite you to share your experiences on it within your organization.

Execute Searchhelp with Search Exit in Background

$
0
0

Hy everybody,

 

i recently had the requirement to get the values of an existing searchhelp. Pretty simple when u are dialog modus. But unfortunatly the requirement was, that the search help had to be called in backgroud without opening the searchhelp dynpros (it's called in a oData Service Implementation).

 

I didn't want to recreate the existing search logic, because it wasn't a simple search help. Most of the logic has been put in a search help exit and i didn't want to write any kind of wrapper by myself.

 

I would like to share following code with u, so next time somebody has this requirement, less research has to be done.

 

r my requirement this solution works fine. I think you can use it as approach when u have similiar requirements

 

*&---------------------------------------------------------------------* *& Report  ZZTAB_SHLP_BG *& *&---------------------------------------------------------------------*
*& Albrecht Michael, 28.01.2015 *&
*&---------------------------------------------------------------------*
REPORT zztab_shlp_bg. DATA:
lv_search_help      TYPE ddobjname,      
lv_search_help_f4if TYPE shlpname. DATA: lt_return_tab        TYPE STANDARD TABLE OF ddshretval,       ls_search_help_infos TYPE dd30v. PARAMETER: p_shlp TYPE string DEFAULT 'Z_PROPSP'. START-OF-SELECTION.   lv_search_help = p_shlp.   lv_search_help_f4if = lv_search_help. * Get Search Help Information   CALL FUNCTION 'DDIF_SHLP_GET'     EXPORTING       name          = lv_search_help     IMPORTING       dd30v_wa      = ls_search_help_infos     EXCEPTIONS       illegal_input = 1       OTHERS        = 2.   IF sy-subrc <> 0. * Implement suitable error handling here   ENDIF. * Call Search Help in Background   CALL FUNCTION 'F4IF_FIELD_VALUE_REQUEST'     EXPORTING       tabname             = ls_search_help_infos-selmethod       fieldname           = ''       searchhelp          = lv_search_help       value               = '*'       display             = ' '       suppress_recordlist = 'X'       selection_screen    = ' '     TABLES       return_tab          = lt_return_tab     EXCEPTIONS       field_not_found     = 1       no_help_for_field   = 2       inconsistent_help   = 3       no_values_found     = 4       OTHERS              = 5.   IF sy-subrc <> 0. * Implement suitable error handling here   ENDIF.

Smartforms & Logos

$
0
0

Dealing with logos in Smartforms has always been a big problem. It never matches the client's requirements and as a result it's always a support call that I've dreaded receiving.

 

The first problem is uploading with a normal 24bit bitmap version of your source image.

Untitled.png

Which gives you this staggered gradient and forces you to have an off-white background to the logo on all forms. Definitely not what the client wants...

 

All over the internet, the solution is to change your logo to 256 colors to make the background of the logo completely white. But then you end up with this.Untitled.png

Which looks even worse in my opinion. Don't despair however. There is a solution. It's called Dithering.

 

I'm providing the Gimp tool's screenshots since it's completely free and comparable to Photoshop, if only for it's functionality and not it's user-interface. So step 1, open the source image in Gimp and then click on Image > Mode > Indexed.

 

Untitled.png

 

Then set up the settings as follows; Note the Dithering option.

 

Untitled.png

 

Finally, choose File > Export As and select Windows Bitmap. No need to change any compatibility settings as your image is already on 256 colors.

 

And here's the result.

 

Untitled.png

That's pretty close to the original if you ask me, especially at this scale.

 

Hope this was useful.

 

As a final note, try and fit your image onto the Smartform at 100dpi once you've made the above changes. I've noticed that SAP's image compression when you up the DPI makes the logo look terrible again.

ABAP Dump Texts - Quick and Dirty

$
0
0

Matthew Billingham has written a helpful blog about ABAP dumps.

 

From my point of view a lot of helpful information is already contained in the short dump texts.

 

You might be interested to see these texts without having to raise the exception.

 

The following - quick and dirty - program can be used as a starting point.

 

Simply enter the dump id, e.g. COMPUTE_INT_ZERODIVIDE or TIME_OUT, in the selection screen and see the short dump text.

 

Kind of poor man's ST22.

 

No guarantee that it works in all cases. I tested some. Feel free to report errors or to improve that little hack.


REPORT ...

PARAMETERS errid TYPE snapt-errid.


CLASS write_dump DEFINITION.

  PUBLIC SECTION.
    CLASS-METHODS main.
  PRIVATE SECTION.
    CLASS-METHODS write_section
      IMPORTING VALUE(errid) LIKE errid
                section      TYPE snapt-ttype.
ENDCLASS.

CLASS write_dump IMPLEMENTATION.
  METHOD main.
    WRITE / errid COLOR COL_HEADING.
    SKIP.
    WRITE / 'What happened?' COLOR COL_HEADING.
    write_section( errid = errid
                   section  = 'W' ).
    SKIP.
    WRITE / 'What can I do?' COLOR COL_HEADING.
    write_section( errid = errid
                   section  = 'T' ).
    SKIP.
    WRITE / 'Error analysis' COLOR COL_HEADING.
    write_section( errid = errid
                   section  = 'U' ).
    SKIP.
    WRITE / 'Hints for Error handling' COLOR COL_HEADING.
    write_section( errid = errid
                   section  = 'H' ).
    SKIP.
    WRITE / 'Internal notes' COLOR COL_HEADING.
    write_section( errid = errid
                   section  = 'I' ).
    SKIP.
  ENDMETHOD.
  METHOD write_section.
    DATA tline   TYPE snapt-tline.
    DATA sect    TYPE snapt-ttype.
    SELECT tline ttype
           FROM snapt INTO (tline,sect)
           WHERE langu = sy-langu AND
                 errid = errid AND
                 ttype = section
                 ORDER BY seqno.
      IF strlen( tline ) >= 8 AND
         tline(8) = '&INCLUDE'.
        REPLACE '&INCLUDE' IN tline WITH ``.
        CONDENSE tline.
        errid = tline.
        write_section( errid = errid
                       section = sect ).
      ELSE.
        WRITE / tline.
      ENDIF.
    ENDSELECT.
  ENDMETHOD.
ENDCLASS.

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

FM to get SD Document Flow

$
0
0

I'm writing this post in order to help others who have difficulties finding the correct SD document flow by accessing directly to standard tables. SAP provides us with a function module called SD_DOCUMENT_FLOW_GET, it's very easy to use and fast enough to look for all the documents in the flow. To give you an example I'll use an Outbound delivery, but you can you any SD document such as Sales Orders, Invoices, etc:

 

1. Let's go to transaction SE37 and in parameter IV_DOCNUM enter the Outbound delivery number:

foto1.png

 

2. We get the list of the SD document flow for the Outbound delivery, for our example there are seven documents:

 

foto2.png

 

3. Let's open the table ET_DOCFLOW to see all documents:

 

foto3.png

 

4. The fields of these table are important:

 

DOCNUM: SD document number.

FOCUS:     Points the document from which the search began.

HLEVEL:    Hierarchy position on the document flow tree.

VBTYP_N: SD document category (type of document for DOCNUM field). In our example we have the following:

 

CategoryDescription
COrder
JDelivery
RGoods movement
MInvoice
8Shipment

 

You can check the complete list of categories by looking the VBTYP domain's values in transaction SE11:

 

foto4.png

 

And that's all we get the SD documents from the order up to the accounting document in FI. As an advice you should order the table by the fields ERDAT and ERZET in descending order to see the documents by the date they were created.

 

I hope this help you with your SD Abap developments.

Core Data Services (CDS) ABAP Feature Matrix

$
0
0

With SAP NW ABAP 7.4 SP5 the first instalment of Core Data Services (CDS) support in ABAP was delivered (see New Data Modeling Features in SAP NW ABAP 7.4 SP5). Since CDS is a relatively new technology, new features are constantly being added. Below is a short overview of which features were released with which SAP NW ABAP 7.4 support package. For details about the features you should check out the 7.40 ABAP Keyword Documentation.

 

Core Data Services (CDS) ABAP View Building

 

Featuresince SAP NW ABAP 7.4 SP5since SAP NW ABAP 7.4 SP8
SQL Joins
  • INNER JOIN
  • LEFT OUTER JOIN
  • RIGHT OUTER JOIN
SQL Set Operations
  • UNION
  • UNION ALL
SELECT Clauses
  • WHERE
  • GROUP BY
  • HAVING
  • AS
Aggregate Functions
  • AVG
  • MAX
  • MIN
  • SUM
  • COUNT( DISTINCT )
  • COUNT( * )
Literals
  • In SELECT list, e.g.: 'literal' AS fieldName
  • As RHS value
Arithmetic Operators
  • +
  • -
  • *
  • / (Float-based division)
Numeric Functions
  • CEIL
  • MOD
  • ABS
  • DIV (Integer-based division)
  • DIVISION (Decimal-based division)
  • FLOOR
  • ROUND
String Functions
  • SUBSTRING
  • LPAD
  • CONCAT
  • REPLACE
Other Functions
  • CAST to built-in DDIC types, e.g.: abap.fltp
  • COALESCE
  • CURRENCY_CONVERSION
  • UNIT_CONVERSION
  • DECIMAL_SHIFT
Conditional (CASE) Expressions
  • "Simple" CASE (behaves like switch statement)
  • Nested CASE statements
  • "Searched" CASE (behaves like if ... else if)
Conditional Expressions
  • Boolean Operators
    • NOT, AND, OR
  • Comparison Operators
    • BETWEEN, =, <>, <, >, <=, >=, LIKE
    • IS [NOT] NULL**

 

**Only in WHERE conditions

Extensibility

$EXTENSION.* (support for database table extensions)

EXTEND VIEW**

 

** Added elements cannot be input parameters, path expressions or aggregate expressions

(Unmanaged) Associations
  • Path expressions in
    • SELECT list
    • FROM clause
    • WHERE clause
    • HAVING clause
  • Filter conditions in path expressions, e.g.: products._texts[ langu = 'EN' ] as english_name

"Core" Annotations

  • End-user Texts
  • (Implicit) Client Handling
  • SAP Buffering
  • Reference Fields for amounts/quantities
  • Data Aging
  • Compiler (compare filter conditions of path expressions to reduce number of JOINs)
Other
  • KEY elements
  • Input parameters

How to debug an RFC function module.

$
0
0

Debugging a RFC:


1. Set External breakpoint in the target server. Keep a breakpoint in the current system before the the RFC statement.


2. Go to tcode SRDEBUG and activate debugging. Give User ID and Select ‘all Appl.Servers’ and ‘External breakpoints already set’ radiobuttons.


3. This gives a new pop-up which says ‘End Debugging: Yes/No:’. Click ‘Yes’ only after the task is completed.


4. Run the program from the current system.  When we get to the call replace the name of the Destination to Temp one which has a temp dialog user. Then on F5 will start a new debugging screen when it comes to RFC call of the function module.


The catch here is the existing RFC destination will not have a dialog user and we need to have a dialog user for debugging to happen.


For this ask Basis to create a temporary RFC destination and give a dialog user till we test the RFC development. We can’t change the RFC destination which we regulary use as lot of Interfaces might depend on it.

Viewing all 948 articles
Browse latest View live


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