Sunday, November 23, 2008

SAP R/3 : READ_TEXT and WRITE_TEXT

In any SAP modules' standard screen functions, users and functionals get to maintain certain text like remarks, vendor notes, and others important elements in the header. These extra notes are stored somwhere in SAP's transparent table. Furthermore, SAP forms and customize forms also make use abundant of such feature like having a certain format of signature stored somewhere at a specific location and later read out to the template for printing or viewing.

These are what I call free texts that is non specific that is not specifically catered by SAP to be saved by certain fields. Hence, these texts are not similar to fields like BUKRS, MATNR, or MEINS but its of RAW format.

"RAW text is a machine readable form of characters or string of characters that is before being process by any analytical software, in this case our very own SAP"

RAW text is gibberish to any developer's view. User or functional will not be able to read it straight from SE16. SE16 won't even show this field that contains RAW format. RAW format for this entry I am referring to non other tables than STXH and STXL. All your free text wheter used in SAPScript or standard screens are stored here in STXL. TCODES such as SO10 and SE75 are both tools for you to create text. Underlying code that keeps such data are RAW format. So the question will be how do i see those RAW text without using those TCODES?

You will need the following functino module : 'READ_TEXT', 'EDIT_TEXT', 'WRITE_TEXT' and so on. You can always refer to this function module's documentation to know more about STXH and STXL tables. Afterall, this is one functino module provided by SAP for you to see RAW format.

This function module is an analytic processing logic to read RAW formatted string of characters. As an ABAP developer, this function module is your next best girl friend to develop/maintain your SAPScript fonts or programs that need to extract long text out from the system.

Another alternative, you can go to SPRO to maintain it.

SPRO->IMG->TO CONFIG TEXT ID
STXH is the text header transparent table
STXL is the text line transparent table
STXD is the text file header

In addition to the above, I found several tables that normally associates itself to RAW format are as follows :
1. VBBP (Billing)
2. EBAN (Requisition)
3. BELEG (JV)
4. PMS (Project and WBS)

I list the following above in the following order of what I usually get acquainted with my daily assignments.

Here's a link that I'd found:
is sky the limit... read text and write text for RAW

Thursday, October 16, 2008

SAP R/3 : LOTUS Notes Receive .SCR File

Editor: This will be a simple entry. Source of error is directed at email format receiving at your email end has error.

Email content displayed as .SCR. Recently, my development with SO_NEW_DOCUMENT_SEND_API1 had a problem which my email display its content incorrectly. Instead of the content I wanted, it was attached with a file. This file is a .SCR file. I am using LOTUS Mail and this error had occured at my workplace. I am not sure if any of you guys using other type of email servers having this error. Maybe Microsoft Exchange does not have this issue at all.

Nevertheless, if you come across this issue, you can check out this OSS notes 171698. Again, the attachment in the email display your contents with .SCR file format. This normally occurs if your developer uses SO_NEW_DOCUMENT_SEND_API1 to send notification to users. The problem is not restricted to this FM but other send email function modules too.

OSS noteNote 171698 - SAPconnect: Formats, conversion, and device type.

is sky the limit... 171698, Email as .SCR

SAP R/3 : Spelling Currency to Words

There are a few ways to spell currency into words. However, it is limited to few languages and its denominations that you can maintain in the T015Z table or your server's language. In order to spell a string of currency, for example, USD 102034.00 or VN 23,000 then you will either need to use an SAP standard FM or you might need to write it out yourself. Here are some options:

1. Call function 'SPELL_AMOUNT'
2. Call function 'HR_IN_CHG_INR_WRDS'
3. Customized a function to convert currency that is not supported by SAP

PS: Another option is check SCC4 for your language/currency or see table T015z or TCURC for currency.

is sky the limit... currency to wordings

Saturday, September 20, 2008

SAP ECC6.0 : Proper customer table creation...

Editor: I will not touch SE11's EVENT MODIFICATION under Table Maintenance Generator. I will probably do it at a later period.

Every company have their own customize development guidelines for customer table developments. Specific naming convention and specific type of data declaration. All this are part and puzzle of development team rules. Unfortunately, I observed that this doesn't really help much when it comes down to gist of realization of what fields should be included into a customize table. I emphasized here about what fields should be used because we are only, as usual, informed which fields will be required by our functionals. Essentially they only want to see and use that particular fields. However what of other additional fields that is required for your proper development? This entry, I want to share with you of my experience in customize table development.

A proper customized table as required by functionals should always has the following structure:(I did not purposely come out with this recommendation because of ECC6, I'd practiced doing this since 4.6c. Moreover, this practice was passed it down from one of my seniors who is now in Singapore!)

MANDT (this is to tell which data belongingto which client)
KEY FIELD 1 - CHECK TABLE (it can be your required field)
KEY FIELD 2 - CHECK TABLE (it can be your required field)
...
KEY FIELD n
non key field 1 - CHECK TABLE (it can be your required field)
non key field 2 - CHECK TABLE (it can be your required field)
...
non key field n
CHECKBOX 1 (optional)
...
CHECKBOX n
CREATED ON
CREATED AT
CREATED BY
CHANGED ON
CHANGED AT
CHANGED BY
Observed those additional fields especially CREATED ON until CHANGED BY fields. Those fields will help your user to especially keep track of line data's accountability. With these fields users are able to monitor who at a certain period created this or update the line item. This can be important when it comes to troubleshooting and determination of responsibility and safety (compromised?). It may not be as important but there may be expectation that this fields can be made use in future (who knows) to be use part of report filtering.

Yes, you may not need to do this, because at the SE16, you can view your CHANGE LOG feature. This feature is only guaranteed if your customized table had its "Changed Log" checked at Technical Attributes in SE11. So it is still fine that those additional fields are put in. As i said, you might never know when an executive or someone from the department comes over to you and ask "Who change the table's data?". So credibility on this part plays a great deal!.

Though now we had moved from 4.6c to ECC6, SE11 had made several changes which included a new feature called 'Enhancement'. You can actually regulate your customize program whether the next developer can change the fields, specific fields, or cannot change the customize program at all. Look it up, my friend. You won't miss it because everytime you activate your customized table, there will always be a WARNING message telling you that this table is not set for certain enhancement!.

is sky the limit... proper customized table

Tuesday, September 16, 2008

SAP R/3 : ALV Limitation...

ALV report itself is a nice tool that allow developers to quickly come out with a nice report that does not require much of programming to build columns, pump in data, sort it, or providing it a few icons or additional instructions. Allowing you to focus on processing data only. Unfortunately, ALV report itself presents a few problems or limitations that somehow hampers our requirements when it comes to large and long report that user wants.

OSS Notes : 857823
Detailing that cells with CHAR or STRING type are truncated after 128. This affects ALV Grid function control and some other SAPGUI display. This is a standard behavior.

OSS Notes : 910300
Next, this notes detailing (UNICODE) that it is also a program limitation for ALV Grid that truncates text. The only solution is to modify the program to only take in a maximum of 42 character for a cell.

OSS Notes : 959775
Also, ALV GRID column of text based cells are truncated or replace '...' so to display that there are more text after that position. This is considered by SAP as an error. You might include the layout method optimize_colwidth = 'X' but it is not the solution but applying SAP Patch.
PATCH : SAPGUI 640 PATCH 21 (Release since 6.0)

OSS Notes : 78401
In addition, last year, I did mention there's another limitation to downloading xls from ALV. Here is the link: http://isskythelimittechnical.blogspot.com/2007/02/sap-r3-spool-converting-report-to-xls.html



Reference : 857823, 910300 and 959775 and obtain from https://www.sdn.sap.com/irj/sdn/thread?messageID=4770708#4770708

is sky the limit... alv grid limitation...

SAP R/3 : Overcome ALV limitations...

As an alternative solution to make your icon in ALV to download xls file smoothly as a result of a few notes due to http://isskythelimittechnical.blogspot.com/2008/09/sap-r3-alv-limitation.html

I would normally recommend a few options:
1. IF your ALV is a list (not GRID), and your xls downloads are messy, most probably, the spool does not recognize the vertical lines from the list. Spool buffers often recognize ALV grid's vertical line as the optical border to help it separate the columns neatly. Solution: convert your report to grid.

2. IF your ALV GRID, present a problem during xls downloads, you might want to consult BASIS to enable the spool to collect more than its limited number of column. Or, you can go to SPAD and modify the spool column.

3. IF your ALV GRID, present a problem during xls downloads, and your BASIS does not want to modify it for fear of other situations - you can custom your standard ALV toolbar's xls icon to download using FM GUI_DOWNLOAD.

(Use SE41) Modifying ALV toolbar is not difficult. You can disable certain ICONS from the ALV toolbar which you do not want user to use it. You can even enable a custom ICON into the standard ALV toolbar so to fullfil user requirement. Thus there are two objects that you need to know in order to custom standard ALV toolbar:

Program : SAPLKKBL
Status : STANDARD*

Copy that status and re-paste it to your custom program. Copy button will popup a dialogue that allows you to transfer that copied ALV status to yours. From there you can edit the toolbar's icon you like.

You will know which icon to modify because xls button is easily recognized by its excels spreadsheet avatar. At the function portion for that xls button, change the function code to your own zXXX so you can use it during CALLBACK from your ALV report.

However, there are 2 things you need to do before you can use your custom xls icon. First, at your ALV function module, you call I_CALLBACK_PF_STATUS_SET to set your copied status so your custom ALV toolbar appears at the report. Second, use I_CALLBACK_USER_COMMAND to trigger your GUI_DOWNLOAD to download your excel files. I_CALLBACK_USER_COMMAND will throw your icon's function code to sy-ucomm.

There you are, in conclusion, a neat step to overcome your ALV problems. I hope there will be more solutions being handled by SAP ECC6.0. Any one who has other alternative solution or some steps I miss you can email to me personally.

is sky the limit... managing your excel download...

SAP R/3 : GET PERNR or SELECT or PROVIDE...

To access employee's record in HR module are multiple ways of doing so. You can use GET PERNR, SELECT, PROVIDE or even function modules. However, the question lies on the difference of each of this syntaxes that allows you to access employee information when we are using it for reporting, enhancement and other data queries.

First, GET PERNR is a macro that contains PROVIDE statements and a logic of filteration based on the logical database PNP. GET PERNR allows you to focus on processing data immediately and less worry on the data selection because the PNP automatically provide a set of predefine group of selection screens. You can even modify and set your own selection screens using HR Report Category and still able to use GET PERNR. HR macros are all stored in this table TRMAC. You will see that each of this line items in that table are specific ABAP coding. GET PERNR should be use when your reporting does not max out the database processing (where there is many read and write) or mass processing. Mass processing will not be very suitable to be queried by GET PERNR. GET PERNR gets each record of an employee of a cycle. Each cycle in GET PERNR does 4 events that will listen to set handler to get data, process data, present data and lastly checking if there are user exit or enhancement to the GET PERNR.

Second, SELECT statement/syntaxes are more suitable to query for large data (mass processing) especially if you are downloading employee data at one shot to a text file or to an IDOC for data transfer. You should use SELECT statement to select a lot of employees for a certain condition so to minimise table read transaction so your performance in an ABAP program can focus more on ABAP processing. In my personal opinion, getting side topic a bit, analysis result yield by SE30 after checking a certain ABAP program should have its performance shoulder towards on ABAP processing side. In other words, it is okay to see the percentage falls towards ABAP processing rather than sliding towards database read. High percentage of database reads indicates your program contains a lot of SELECT SINGLE and a whole START-OF-SELECTION filled with SELECT-END SELECT statements. Worse, there might be a possibility that your program contains NESTED SELECT statement. You should group your SELECT statement in one place and gather all data before going to processing stage.

Third, a good mixture usage of GET PERNR and INFOTYPE syntax can help you ease your HR report processing reading your infotype tables a great deal. At each read of GET PERNR, INFOTYPE syntax will be automatically filled with data related to the particular employee so it helps you to reduce coding and in one way, getting correct rows of record for an employee that is time dependent. Time dependent in HR meaning each record of transaction for an employee has a trace of time that dictates the time and date that affect that record. Not all infotype is dependent time. Infotype like 0000 (Action) is time dependent because it can tell you when an employee is recruited, confirm, transfer, promoted, terminated or on leave.

GET PERNR and SELECT statement should be used accordingly to reporting condition. GET PERNR sometime can slows down your report. Also, instead of using PROVIDE statement, you should use GET PERNR because PROVIDE is in the macro itself.

is sky the limit... GET PERNR/PROVIDE/SELECT

Wednesday, May 14, 2008

SAP R/3 : Trailing The Pricing Condition

Last several weeks, an unusual incident occured at the area of pricing condition in which one of the pricing (condition type) is not populating price correctly. Initial coding were done in one of the user exit to recorrect the value. However, the value was not updated as the functional wanted. So I had to follow the trail of Indiana Jones by tracing the standard program. So below is one of the gruesome steps on how the pricing condition was determine during invoice creation (VF01).

Put a break point accordingly to each of the path below:

1. SAPMV60A (Travel Here)
*****>MV60AF0X_XKOMFK_ENDE
**********>RV_INVOICE_CREATE

2. SAPLV60A (Travel Here)
*****>LV60AU01
********>PERFORM FAKTURA_ERZEUGEN

3. SAPLV60A (Travel Here)
*****>LV60AA26
********>PERFORM FAKTURA_LIEFERBEZ0GEN

4. SAPLV60A (Travel Here)
*****>LV60AA22
********>PERFORM FAKTURAPOSI_LIEFERBZ0GEN

5. SAPLV60A (Travel Here)
*****>LV60AA21
********>PRICING_COPY
******>(INITIALLY JIN1 KWERT IS STILL 0.00)<br>
6. SAPLV60A (Travel Here)
*****>LV60AA60
********>PRICING
******>(At this point, JIN1 KWERT WAS REINITIALIZE TO 0.22 -> Which We do not WANT!)<br>
7. SAPLV61A (Travel Here)
*****>LV61AU01
********>PERFORM XKOMV_BEWERTEN
******>(How all 0.22 started)

8. SAPLV61A (Travel Here)
*****>LV61AA55
********>XKOMV_BEWERTEN
******>(91 - LOOP AT XKOMV - WHERE IT ALL HAPPEN!)
******> KSTEU and KMPRG (This is the two brothers that caused it!)


Therefore, we had the good owner to initialize the KSTEU and KMPRG to a certain value so it the value can be remain as the Functional wanted to meet the requirements.

is sky the limit... pricing procedures rocks!

SAP R/3 : User Exits in VF01

Something to help everyone on all the userexits and BADI for transaction code VF01. VF01 is to create invoice. Below are the list of all userexits and some BADI invoke (maybe). In which of late, i had a headache to check out why VF01 had problem in creating invoice successfully.


EXIT_SAPLV60B_006
EXIT_SAPLV60B_002
EXIT_SAPLKBER_002
COPA_CALL_CUSTOMER_EXIT_KEAB04
EXIT_SAPLKEAB_003
SD_CIN_LV60AU02
EXIT_SAPLMCS6_000
EXIT_SAPLMCS6_999
EXIT_SAPLMCS6_001
BADI_SD_DOCUMENTFLOW
IDOC_OUTPUT_INVOIC

SDVFX010 - for those who wants to do something during SAVE

In any way, if you find this user exit unable to help you and would want to know more if there are other user exits. You can always punch up the ST05 to do an analysis on your VF01.



is sky the limit... user exits on VF01

Tuesday, May 06, 2008

SAP R/3 : Sending Multiple PDF Invoice From Output Type

Sending email with an invoice attached to it has never occured to me if it can be done without the working mechanism of business workflow. The requirement was fairly simple during discussion and it was seriously sounded simple enough to put it straight to development immediately. However, I am not very familiar with business workflow. So the question now was how am I going to send an email out with an invoice attach to it. So here is the requirement in question:


"When user create an invoice via VF01 or from a customized IDOC that creates invoice, several output types are created and one of them is an outbound IDOC that will send back to the sender to let them know invoice has been created. Now, after the invoice and IDOC has been sent out, there should be a mechanism to check whether the outbound IDOC is successfully send out. If it is successfully sent out, the mechanism will grab that invoice, convert it to PDF, attach it to an email and send it to responsible recipients..."


Oh boy, it sounds easy to one who is not aware of the workaround behind or does it sounds very technical to one who has minimal working knowledge on it? I was the latter. So below are some of the questions which had formed in my brain:


1. How do you grab an invoice which has been produced by the system (VF01)?
The CLOSE_FORM function module will return a spool no when the SAPSCript has finish processing and display.
2. How do you convert an invoice to a PDF?
The CONVERT_OTFSPOOLJOB_2_PDF function module take the input of SAPScript and returns in PDF format.

3. How do you attach a PDF to the email?
The SO_NEW_DOCUMENT_ATT_SEND_API1 function module will hold the PDF

4. How do you send an email?
The SO_NEW_DOCUMENT_ATT_SEND_API1 function module will hold the PDF and send the email


After giving some thoughts to those questions above, now comes the big part of the whole mother of all questions:

How on earth at which point in the VF01 should I initiate this whole process?

So the my mind start to processing again. The answer to this might be using USER EXITS or Business Add-Ins (BADI). These two solutions seem to be the most absolute answer to the problem. However, when I revealed a solution at the end of this entry, you might find it with disbelief. But to the very few people who started with that solution was real good! Now, let me tell you what I had implemented initially to cater to that problem.

I went ahead to ST05 to get down all the USER EXITS and BADI from VF01 so I see which of them are more suitable to initiate this process. Doing so, I'd found one, it was XXXX. At this point, my imagination went beyond. Somehow, it is sometimes bad to venture too far from my own imagination. Because the next step I wanted to know how do I check the outbound IDOC's status from this USER EXIT XXX. It was simple, I used transparent table NAST and EDIDC to check the outbound IDOC's status. If its status are 03, 30 and XX, then it should go ahead to process the invoice convertion and IDOC send out. For the time being I'd solved 2 major problems.


Next, I need to get the latest invoice to do conversion. Unfortunately, with the current USER EXIT, I might not be able to get that SPOOL ID because it has not been created yet. VF01 has to be finished first. This pose another problem, how do I let VF01 finish off so I can get the SPOOL ID? After an overnight sleep, I decided that creating another RFC function module in the USER EXIT will do the trick. An RFC that executes with a new process created in the background. Thus, with this RFC initated as a new process run and letting the VF01 to finish processing, I can get the SPOOL ID.
Hence, I was definitely sure that my concept will surely work. However that will not work. Because of the RFC that i am using, it will cause overlapping. If you ever do my silly method, you will come across overlapping problem. RFC does not care if your PDF has been generated and sent by previoius document. It will just grab and resent everything including the new. Thus, my way does not work.


The only solution is to have the PDF converted, attached and sent from the print program. Not only does this eliminate duplicates of document but will ensure that it will not sent out duplicate copies of form due to overlapping. Printprogram should be any program that is used to process and display your SAPScript. For any standard program that prints forms, you can go to NACE to find out which program and form that it is using for print out. This way you also know the output type that is used by the standard program.


is sky the limit.... print, converting and sending...



SAP R/3 : Tracing Outbound IDOC

Troubleshooting outbound IDOCS can be very exciting and interesting activity. You get to see the wonders of sending data out of SAP to some other 3rd party systems. If you are unaware of some technicalities and behavorial of outbound IDOCS then testing it can be quite a challenge. Recently, I had this problem of trying to trace an outbound IDOC.

Previously, I could trace the outbound IDOC with minimal difficulty in WE19. If you put a break-point in your outbound process code or function module, the WE19 will stop at that point. But, what if WE19 fails to stop at that point? You will be scratching your head until you reach to a certain point you want to write an extra program just to trace the outbound IDOC. That is just what i did. Read my statement, I wrote an extra program to do that.

Though its a bit consuming but if you know which table and which fields to use then the concept will work just like the my now ever loving standard output type program RSNAST00. I shall have to thanks one person who let me know this existing program. But first, I would like to let you know what I'd gone through the latter method.

To developed an extra program to trace outbound programs is not as difficult as it seems. All you need is declare three tables i.e. NAST, EDIDC and EDID4. NAST is the output type control table that stores all of your 6 output types from printout to telefax. EDIDC is the IDOC control table. EDID4 is the IDOC data table. Therefore, you need to access the first table, NAST, in order to get the output type that you are supposed to execute. After you had obtain the necessary data from NAST, you will need to approach the EDIDC to get the DOCNUM and subsequently the EDID4 for its data. Then you pass all these three data selected data to your outbound's function module. Therefore, you can primitively test your outbound data. However, you will still need to set your output type to be scheduled run at other time.

Now, let us move on to life saving method to test your outbound IDOC or output types. In any of your standard programs that can send out IDOC, Telefax, Print out, set it to 1 (scheduled run at other time) in the FURTHER DATA section. Then you turn to RSNAST00 program where you put in your APPLICATION, OBJECT KEY, MEDIUM and OUTPUT TYPE. Before executing, put a break-point at your function module. Then you are ready to trace your outbound IDOC.

A note, the RSNAST00 does not only let you trace your outbound IDOC it is in fact a standard program that let you execute output types that you have schedule for later run. Hence, a very great thanks to Vincent Teoh from the SD (Sales and Distribution) module team. The RSNAST00 had definitely helped me a lot. Though I am still keeping my old program for reference. Concept still work very the same like RSNAST00.

is sky the limit... RSNAST00 and NAST, EDIDC, EDID4