What is SY-ONCOM? - abap

What is sy-oncom used for?
I've the following explanation from SDN but in my program I'm getting a value of 'T' and 'X'.
SY-ONCOM
On Commit flag. This system field is
set to different values depending on
the call status of an ABAP program. Of
these, only the value of ‘P’ is
guaranteed. If at all, SY-ONCOM must
only be queried for ‘P’.
The value 'P' means that the program
is already executing a subroutine
started using PERFORM … ON COMMIT and
therefore a further subroutine call
using PERFORM ... ON COMMIT would
cause a runtime error.

It's a largely undocumented field, I wouldn't rely on it. I know that it should be set to 'V' (Verbucher) when an update function module is run in the update task after COMMIT WORK. Before this, the PERFORM foo ON COMMIT calls are executed, and during these routines, the field should be set to 'P'.
Just out of curiosity, what do you need it for?

Related

Does ABAP CALL statement set SY-SUBRC value?

I'm looking at the description of CALL - System Function Call in the SAP ABAP Keyword Definition. Such calls have the format CALL 'xxx' ID 'yyy' FIELD 'zzz'. The ABAP Keyword Definition does not mention that sy-subrc is set by calling a system function. But somehow, I suspect that it is.
Can I "trust" the Keyword Definition in such a case? (sy-subrc not mentioned => not set)
What would be a "good" example system function call to test it on an SAP system? (does not break/change anything, exists on all systems)
Note that I'm not an ABAP programmer and I usually handle third-party ABAP programs in Java as text / parse tree. I know that one usually should not call system functions, but the ABAP code I look at might have such calls. Furthermore, I'm not interested in the actual value a specific system call sets sy-subrc to, just in the fact whether system calls set/alter sy-subrc or not.
Well, as you are asking this question you are already aware this is NOT recommended approach to use direct SYSTEM calls. However, if you still want to use them...
By using CALL statement SAP kernel C-modules are called and without knowing the source we can not interpret the returning value confidently, either it's 0 or 1.
Despite there are examples (see line 230 of DYNP_VALUES_READ FM) where sy-subrc value is checked after system calls, nobody except SAP knows which value to check in certain case. Nor we.
Also there were reports (1, 2) about ambiguous meaning of these values during tests.
So the answer is NO, sy-subrc in this context brings no meaningful information.
P.S. Answering your questions:
No, you cannot interpret it that way. If something is not mentioned in ABAP Documentation then this not known for sure or not meaningful at all.
I cannot confirm this is good idea at all (to test system calls), but if you want you can try call SYSTEM function.
It calls arbitrary Unix command. For example, you can move files stored on your ABAP Server like this:
CALL 'SYSTEM'
ID 'COMMAND'
FIELD 'mv /usr/sap/temporary
/usr/sap/definite'.
Now this should be a safe call that works on any system:
DATA: dbserver TYPE char255.
CALL 'C_SAPGPARAM' ID 'NAME' FIELD 'SAPDBHOST'
ID 'VALUE' FIELD dbserver.
As you probably already know there are some exceptions that can occur. As for sy-subrc, when a command sets sy-subrc it is usually explicitly mentioned in the documentation including which values it can hold and their meaning. But don't quote me on that.
Simple (harmless) function modules are RH_GET_DATE_DAYNAME that requires the language and 10 character date (eg. 26.10.2016) as input fields and DATE_TO_DAY that only requires the 10 character date as input. The sy-subrc should be returned as 0 if a valid date is entered.

UFT- Can I get the result of an action during run?

I have created a test with 1 action which contains n actions. Is there any way to check after the execution of each action of the n actions the result if it is fail or pass and proceed accordingly?
Not directly.
A similar idea would be to ask for the current run result status, see How can I get the run result status according to the current report node?, but that is currently unsolved.
You can, however, call your actions, and consume there return value, like this:
ActionSucceeded=RunAction ("myTest [Action2]", oneIteration)
If not ActionSucceeded then
' The Action2 call signalled "failure" (false)
End If
This implies that Action2 must return such a result, like in here:
ExitActionIteration (false)
Beware, however, of the fact that RunAction statements need to be inserted using QTP´s IDE (Insert/Call To Action...), resulting in a RunAction call without brackets. When editing this to the assignment form above (with brackets), make sure you get it right the first time before you save the test -- because if you save a test containing a broken RunAction call, QTP disassociates the called test, and the test will fail at runtime even if you edit the script back to correct syntax. This is due to metainfo that QTP saves invisibly in the script, and if you save an invalid action call, this metainfo is being discarded. (You can see when this happens because the action call will disappear from the test flow view.)
And: If you don´t store the RunAction result in a variable, but use it directly, like in
If not RunAction ("myTest [Action2]", oneIteration) then
' The Action2 call signalled "failure" (false)
End If
the same mess arises: QTP does not understand that this is a valid action call, and it won´t work even if you edit it into back into the original form.
Except for the "beware" hint, the same holds true for LoadAndRunAction, which calls an action at runtime. LoadAndRunAction can be called as a function, and if the called actions returns a value via ExitActionIteration, it returns that value.
Yet another "beware" hint: ExitActionIteration really requires its arguments to be enclosed in brackets, even though it is a Sub (or at least called as a Sub). I suspect this is because it is not a real Sub or Function, but a special statement "patched into" the MS VBScript engine in some exotic way.

Which one is better for me to use: "defer-panic-recover" or checking "if err != nil { //dosomething}" in golang?

I've made a large program that opens and closes files and databases, perform writes and reads on them etc among other things. Since there no such thing as "exception handling in go", and since I didn't really know about "defer" statement and "recover()" function, I applied error checking after every file-open, read-write, database entry etc. E.g.
_,insert_err := stmt.Run(query)
if insert_err != nil{
mylogs.Error(insert_err.Error())
return db_updation_status
}
For this, I define db_updation_status at the beginning as "false" and do not make it "true" until everything in the program goes right.
I've done this in every function, after every operation which I believe could go wrong.
Do you think there's a better way to do this using defer-panic-recover? I read about these here http://golang.org/doc/articles/defer_panic_recover.html, but can't clearly get how to use them. Do these constructs offer something similar to exception-handling? Am I better off without these constructs?
I would really appreciate if someone could explain this to me in a simple language, and/or provide a use case for these constructs and compare them to the type of error handling I've used above.
It's more handy to return error values - they can carry more information (advantage to the client/user) than a two valued bool.
What concerns panic/recover: There are scenarios where their use is completely sane. For example, in a hand written recursive descent parser, it's quite a PITA to "bubble" up an error condition through all the invocation levels. In this example, it's a welcome simplification if there's a deferred recover at the top most (API) level and one can report any kind of error at any invocation level using, for example
panic(fmt.Errorf("Cannot %v in %v", foo, bar))
If an operation can fail and returns an error, than checking this error immediately and handling it properly is idiomatic in go, simple and nice to check if anything gets handled properly.
Don't use defer/recover for such things: Needed cleanup actions are hard to code, especially if stuff gets nested.
The usual way to report an error to a caller is to return an error as an extra return value. The canonical Read method is a well-known instance; it returns a byte count and an error.
But what if the error is unrecoverable? Sometimes the program simply cannot continue.
For this purpose, there is a built-in function panic that in effect creates a run-time error that will stop the program (but see the next section). The function takes a single argument of arbitrary type—often a string—to be printed as the program dies. It's also a way to indicate that something impossible has happened, such as exiting an infinite loop.
http://golang.org/doc/effective_go.html#errors

populating 0LOGSYS from transformation rule

I am trying to populate the infoobject 0LOGSYS in a DSO when a load from a datasource occurs. The idea being that you could tell what sourcesystem the data was loaded from that is needed for a certain requirement. As of now I have a routine set up on a transformation rule for 0LOGSYS. No syntax errors, everything runs during the load, but no data is populated. Tried to debug but for some reason my BREAKPOINT is not getting picked up.
Here is the code that I have placed in the routine. Also, I am trying to do this without assigning any source field so maybe that is causing an issue. Not sure though.
TYPE-POOLS: RSSM.
Data: G_S_MINFO TYPE RSSM_S_MINFO.
CALL FUNCTION 'RSDG_ID_GET_FROM_LOGSYS'
EXPORTING
i_source_system = G_S_MINFO-LOGSYS
IMPORTING
e_soursysid = RESULT
EXCEPTIONS
id_not_found = 1.
Solved this a different way. There are runtime attributes that can be pulled from any request via the methods of "if_rsbk_request_admintab_view" which is instanciated automatically at the beginning of each transformation routine. Here is the code that I put in the routine.
*declaring a local variable like the result type LOGSYS
Data: lvSource like RESULT.
*runs a method to get the source system from the runtime attributes of
*the request
*"p_r_request" is an instance of "if_rsbk_request_admintab_view" which
*has many different methods for runtime attributes
lvSource = p_r_request->GET_LOGSYS( ).
RESULT = lvSource.
If this is the complete source code, it's not surprising that nothing is returned. You declare a new structured variable named G_S_MINFO, don't assign any value to it and return its contents. Unless you deleted the steps from your code sample that are supposed to fill the variable with values, it would be a grave bug if anything else than an initial value was returned.
EDIT: Even with the updated code, I still doubt this will work. Now you pass G_S_MINFO-LOGSYS to a function module that supposedly looks up some system ID without initializing it. Garbage in, garbage out. Or in this case, initial value in, initial value out.

Execute a program via SUBMIT, with GUI suppression

I want to expose the functionality of an SAP program (transaction) as a BAPI.
I need to call a report and supply range filters such that the GUI is bypassed.
Does anyone have a working example of the SUBMIT ... WITH ... ABAP construct, or other suggestions on how to accomplish what I need to do?
Here is a working example:
SUBMIT SAPF140
TO SAP-SPOOL "optional"
SPOOL PARAMETERS print_parameters "optional"
WITHOUT SPOOL DYNPRO "optional (hides the spool pop-up)"
VIA JOB jobname NUMBER l_number "optional"
AND RETURN "optional - returns to the calling prog"
WITH EVENT = REVENT
WITH BUKRS IN RBUKRS
WITH BELNR IN lRBELNR
WITH GJAHR IN RGJAHR
WITH USNAM = SY-UNAME
WITH DATUM = SAVE_DATUM
WITH UZEIT = SAVE_UZEIT
WITH DELDAYS = RDELDAYS
WITH KAUTO = 'X'
WITH RPDEST = SAVE_PDEST
WITH TITLE = TITLE.
All the "WITH" statements relates to selection fields on the called program where I use = it is a PARAMETER statement (single field), where I use IN it is a SELECT_OPTIONS statement (range)
Here is a simple example of how to fill a range:
REFRESH lrbelnr.
lrbelnr-sign = 'I'.
lrbelnr-option = 'EQ'.
lrbelnr-low = HBKORM-belnr.
CLEAR lrbelnr-high.
append lrbelnr.
If you want to suppress this functionality as a BAPI you have to wrap the functionality in a Remote Function Call (RFC) module. Just implement a RFC function module. Depending how the report is implemented, it may use ABAP objects, which can also be called from your RFC implementation. Given that case you have a quite good solution. Whenever the report is adjusted, also your BAPI will reflect the changes. In case it's a standard programm from SAP which cannot be wrapped, think about copying it into your namespace and adjusting it. Nevertheless this might give some hassle, when SAP performs an update via Support Package Stack and you won't realize it. The output of the two methods is different. Apart from that, if you want to call it from outside, there is nothing else possible than implementing a RFC module.
A submit report can not return the values outside. Reports are always only for GUI functionalities and not for exchanging data. In case your report uses select options, you somehow have to implement this feature "by hand" in your RFC, as this statements can not be used inside RFC modules. I would generally try to rework the report, modularize it and put the selection information in a central class or maybe another function module wich can be called from the report and your BAPI function module. The filters you are talking about can not be implemented in RFCs automatically. You have to implement those ranges manually. The warning which comes up cannot be suppressed, if you do a RFC call from a remote system and the popup with the warning comes up you'll end with a shortdump. Therefore, you have to rework the report and to re-implement it for your needs.
If you are just looking for bypassing it via job scheduling, create a variant and schedule the report with that variant but I suppose that's not the solution you're looking for.
You can use inbuilt BAPI also just write "Range" and press F4.
You can wrap your report in an BATCH INPUT session and execute it inside a function. The only drawback is that you need to rewrite the BATCH INPUT every time you change the report.