I would like to get information about a report. I want to know which values are available if I call the report like this:
SUBMIT (IV_REPORT_NAME)
WITH SELECTION-TABLE selection_table
AND RETURN.
Here is my attempt:
FUNCTION /FOO/GET_REPORT_INFO.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" VALUE(IV_REPORT_NAME) TYPE PROGRAMM
*" EXPORTING
*" VALUE(EV_RESULT_JSON) TYPE STRING
*"----------------------------------------------------------------------
DATA:
ld_return TYPE BAPIRET2,
it_selscreen_info TYPE STANDARD TABLE OF BAPI_SELSCREEN_INFO,"TABLES PARAM
wa_selscreen_info LIKE LINE OF it_selscreen_info,
it_selscreen_texts TYPE STANDARD TABLE OF TEXTPOOL,"TABLES PARAM
wa_selscreen_texts LIKE LINE OF it_selscreen_texts,
ld_external_user_name TYPE BAPIXMLOGR-EXTUSER.
ld_external_user_name = 'foo'.
CALL FUNCTION 'BAPI_XBP_READ_SELSCREEN'
EXPORTING
program = IV_REPORT_NAME
external_user_name = ld_external_user_name
IMPORTING
return = ld_return
TABLES
selscreen_info = it_selscreen_info
.
ev_result_json = /ui2/cl_json=>serialize( data = it_selscreen_info pretty_name = /ui2/cl_json=>pretty_mode-low_case ).
IF sy-subrc <> 0.
MESSAGE |Error sy-subrc: { sy-subrc }| TYPE 'E'.
ENDIF.
ENDFUNCTION.
But the result is always empty.
What am I doing wrong? Is BAPI_XBP_READ_SELSCREEN the right method for my goal?
This is an answer about "why BAPI_XBP_READ_SELSCREEN doesn't work", not an answer about the main question which is "how to retrieve selection screen parameters".
I'm not sure, but I guess BAPI_XBP_READ_SELSCREEN doesn't work because you don't apply the usual logic of XBP.
XBP ("eXternal Background Processing") is a library of APIs used to schedule jobs from an external scheduler. It's based on XMI ("eXternal Management Interface" Framework) which is used by other APIs, and which offers common features, especially the log.
XMI and the applications based on XMI are RFC-capable, so that they can be called remotely.
To use the APIs based on XMI, the minimum is to :
call the function module BAPI_XMI_LOGON to open a session to use a library of APIs you want to use.
For XBP, use the parameters INTERFACE = 'XBP' and VERSION = '3.0' (or the version you want).
The parameters EXTCOMPANY and EXTPRODUCT can be any max-16-characters names, as agreed with the administrators of the SAP software (they can be possibly blank too), and are subject to S_XMI_PROD authorizations if defined. If they are used with different XMI API libraries during the same RFC session, the same values must be passed.
call the APIs you want (BAPI_XBP_READ_SELSCREEN in your case).
Note that there's an "external user" parameter (usually EXTERNAL_USER_NAME), which is a free field, to be an identifier of the external application. This value is stored with the logs so that you may display or retrieve the XMI logs by external application (transaction RZ15).
call BAPI_XMI_LOGOFF
There is one INTERFACE parameter, whose value must be the same as the one used in BAPI_XMI_LOGON.
In case, you have called an API which updates data, call BAPI_TRANSACTION_COMMIT to commit these updates.
I've just tested BAPI_XBP_READ_SELSCREEN successfully with the program below (please handle the exceptions), so I think it's a good idea to use it :
DATA rfcdest TYPE rfcdest.
rfcdest = ''. " XBP is well suited for RFC, but this test doesn't need remote call.
CALL FUNCTION 'BAPI_XMI_LOGON'
DESTINATION rfcdest
EXPORTING
extcompany = 'ABAPERS&CO'
extproduct = 'NICEJOBSCHEDULER'
interface = 'XBP'
version = '3.0'.
DATA: selscreen_info TYPE STANDARD TABLE OF bapi_selscreen_info,
selscreen_texts TYPE STANDARD TABLE OF textpool.
CALL FUNCTION 'BAPI_XBP_READ_SELSCREEN'
DESTINATION rfcdest
EXPORTING
program = 'BTCAUX10'
external_user_name = 'SRO'
sel_text_lang = 'E' " English
TABLES
selscreen_info = selscreen_info
selscreen_texts = selscreen_texts.
CALL FUNCTION 'BAPI_XMI_LOGOFF'
DESTINATION rfcdest.
IF rfcdest IS NOT INITIAL. " if you use RFC, close the connection!
CALL FUNCTION 'RFC_CONNECTION_CLOSE'
EXPORTING
destination = rfcdest
EXCEPTIONS
destination_not_open = 1
OTHERS = 2.
ENDIF.
Please check user name "foo". If foo is not external user then result will be empty because of wrong external user.
regards,
Umar Abdullah
Related
I have a requirement were I need to read ABAP code written by SAP developers. I want to write my own client using Java/Python which can integrate with SAP system and get me the ABAP code.
What I understand that ABAP code is stored in SAP database like HANA, mysql etc. So is there a way which SAP provides where we can read the code like we can do in Git/SVN etc.
I've used RFC calls RPY_FUNCTIONMODULE_READ and RPY_FUNCTIONMODULE_READ_NEW through the perl NWRFC wrapper/library to retreive ABAP code.
You can access tables with below techniques:
Using SAP Connectors via RFC (RFC_READ_TABLE)
Using SOAP Web Service with same function (RFC_READ_TABLE)
Using custom web services with existing functions which are reading report, functions, etc.
You can use both Java or Pyhton for RFC, there is already exits github repo for python.
If you will select reading directly in db table, you need to know structure of saved data. It has own mechanism for OOP objects. Daniel Berlin try to implement binary parser in C++ in sap-reposrc-decompressor project. Never forget this source depended with SAP version.
I think using ADT (ABAP Development Tools) plugin is good for updated systems. There is already Eclipse plugin exists for ADT. ADT not exists in old systems.
If you are planning to use your solution in old system (after 7.01), you can build your own solution with abapGit and custom web services.
NOTE: Keep in mind, report and data elements (variables, tables, types) saved in separate tables. Dynpro objects (screens etc), reports (Smartforms) hard things to decompile.
Before you re-invent a wheel, Take a look at:
ABAPgit. https://docs.abapgit.org/
or the old SAPLink https://wiki.scn.sap.com/wiki/display/ABAP/SAPlink.
If you want JUST the source code, You could expose a very simple rest service/ Endpoint in SAP.
This service would just read the raw code and return it as plain text.
Every abaper could create this for you.
BUT is the raw source only. There is much more to a complete development
and why tools like ABAPGIT exist.
In SICF, create a new endpoint / service.
EG ZCODE_MONKEY with the class below as an example.
Now activate the service.
Call the endpoint
http://server:PORT/zcode_monkey?name=ZCODE_MONKEY
Sample implementation
CLASS zcode_monkey DEFINITION
PUBLIC
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: if_http_extension.
ENDCLASS.
CLASS zcode_monkey IMPLEMENTATION.
METHOD if_http_extension~handle_request.
DATA: lo_src type ref to CL_OO_SOURCE,
l_name TYPE string,
l_repname type c length 30,
l_clskey type seoclskey ,
l_source type rswsourcet,
resultcode TYPE string.
FIELD-SYMBOLS: <line> TYPE LINE OF rswsourcet.
l_name = server->request->get_form_field( name = 'NAME' ).
l_clskey = l_name.
l_repname = l_name.
create OBJECT lo_src
EXPORTING
clskey = l_clskey
EXCEPTIONS
class_not_existing = 1
others = 2 .
IF sy-subrc <> 0.
read REPORT l_repname into l_source.
else.
lo_src->read( ).
lo_src->if_oo_clif_source~get_source( IMPORTING source = l_source ).
ENDIF.
LOOP AT l_source ASSIGNING <line>.
CONCATENATE resultCode
cl_abap_char_utilities=>cr_lf
<line>
INTO resultCode RESPECTING BLANKS. " always show respect ;)
ENDLOOP.
SErver->response->set_content_type( content_type = 'text/plain' ).
server->response->set_cdata( EXPORTING data = resultcode ).
server->response->set_status(
EXPORTING
code = 200
reason = 'this is a 3.50 piece of code. Dont ask...its a demo ' ).
ENDMETHOD.
ENDCLASS.
I am trying to use cl_salv_bs_runtime_info in order to get the ALV data in memory after using SUBMIT in a standard report.
The code for the above is:
REPORT ztest1.
FIELD-SYMBOLS <lt_pay_data> TYPE ANY TABLE.
DATA lr_pay_data TYPE REF TO data.
cl_salv_bs_runtime_info=>set(
EXPORTING display = abap_false
metadata = abap_false
data = abap_true ).
SUBMIT rfts7000
AND RETURN.
TRY.
cl_salv_bs_runtime_info=>get_data_ref(
IMPORTING r_data = lr_pay_data ).
ASSIGN lr_pay_data->* TO <lt_pay_data>.
CATCH cx_salv_bs_sc_runtime_info.
MESSAGE `Unable to retrieve ALV data` TYPE 'E'.
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
When it is run the program rfts7000 runs and prompts for data selection.
After submitting the selection screen i get:
ST22 extract:
Any ideas?
After some research based on comments in the relative SCN Question the case is as follows.
The system is throwing this error in order to prevent me from running outdated and obsolete (or soon to be obsolete) programs.
The specific program that i call through SUBMIT, is part of the Cash Management (CM) module which although is still active in S4/HANA , i think that is going to be replaced.
So SAP Note 2392358 says exactly that: "According to the S/4HANA Simplification List, the totals tables of classic CM are completed eliminated and therefore they shall not be accessed any more."
In order for this protection to work, SAP has a blacklist where the programs are listed in order not to be used.
But there is a possible "backdoor" to that as explained in SAP Note 2249880. The backdoor is just a way to remove a program from the Blacklist.
The note suggests to get approval from SAP first and then to follow the steps to remove the program from the blacklist.
As a side note, i worry more that we have implemented cash management in an outdated module rather than worrying about the error after all...
Up to now I get only an error message if something inside my SAP RFC function is wrong
pyrfc._exception.ABAPRuntimeError: RFC_ABAP_MESSAGE (rc=4): key=No authorization,
message=No authorization [MSG: class=00, type=E, number=001, v1-4:=No authorization;;;]
It would increase the development speed a lot if I could get a stacktrace of ABAP function. Is there a way to get a stacktrace like for example in Python?
Related: https://softwarerecs.stackexchange.com/questions/52350/sentry-event-from-exception-to-html
Sentry uses a particular JSON to represent a stacktrace and the content of the local variables. Above link contains an example.
Stack trace inside ABAP can be called
with the class cl_abap_get_call_stack.
Local variables are not included in the stack trace returned by the class cl_abap_get_call_stack.
But you could use a log-point to monitor local variables and the stack trace. Log-points can be created, changed and viewed in transaction saab.
A example code snippet:
DATA(formatted_stack) =
cl_abap_get_call_stack=>format_call_stack_with_struct(
cl_abap_get_call_stack=>get_call_stack( ) ).
LOG-POINT ID my_log_point FIELDS formatted_stack
local_variable1 local_variable2.
For the authorization-error, please check transaction su53.
When you see the red authorization-object S_RFC, it means you are not allowed to call the function module in any way!
With ABAP 753 release there was introduced such structure as EPP - Extended Passport.
It seems to be doing something that you want, i.e. showing trace of the called system. I put "seems to be" because I have no 753+ system by my hands so I cannot check in practice.
From the description it should do what you want:
An Extended Passport (EPP) is a data structure that can be sent from a client to a server and is used to analyze call stacks
Extended Passport can be used by frameworks and analysis tools to track external call stacks in communication between clients and servers beyond system boundaries. The values of the EPP components can be saved to log files and used for monitoring. One example of this are short dumps, which all display the most important EPP components.
The DEMO_EPP gives the following usage pattern of EPP:
cl_demo_epp=>init( ).
"this program
cl_demo_epp=>append( ).
"Calling RFC to remote instance
CALL FUNCTION 'DEMO_RFM_EPP_1' DESTINATION instance.
"New SAP LUW
CALL FUNCTION 'DEMO_UPDATE_DELETE' IN UPDATE TASK
EXPORTING
values = VALUE demo_update_tab( ).
COMMIT WORK.
cl_demo_epp=>append( ).
cl_demo_output=>new(
)->begin_section( `Extended Passport (EPP)`
)->display( name = 'EPP Trace'
data = cl_demo_epp=>get( ) ).
I'm developing an ABAP PROGRAM which calls RFC from differrent SAP systems. Is there any way to check if the RFC exists in the destination system before calling the RFC?
You can use FM FUNCTION_EXISTS to check, if an FM exists or not. Obviously you have to call it remotly. Roughly:
CALL FUNCTION 'FUNCTION_EXISTS'
DESTINATION ...
EXPORTING
funcname = 'xxx' => enter the FM here, which has to be checked
* IMPORTING
* GROUP =
* INCLUDE =
* NAMESPACE =
* STR_AREA =
EXCEPTIONS
FUNCTION_NOT_EXIST = 1
OTHERS = 2.
If the FM exists, the importing parameters will have valid values, otherwise FUNCTION_NOT_EXIT exception will be raised.
Most common way in my opinion is to use RFC_PING:
CALL FUNCTION 'RFC_PING' DESTINATION <your destination here>.
I want to run a Bigquery SQL query using insert method.
I ran the following code just like so:
JobConfigurationQuery = Google::Apis::BigqueryV2::JobConfigurationQuery
bq = Google::Apis::BigqueryV2::BigqueryService.new
scopes = [Google::Apis::BigqueryV2::AUTH_BIGQUERY]
bq.authorization = Google::Auth.get_application_default(scopes)
bq.authorization.fetch_access_token!
query_config = {query: "select colA from [dataset.table]"}
qr = JobConfigurationQuery.new(configuration:{query: query_config})
bq.insert_job(projectId, qr)
and I got an error as below:
Caught error invalid: Job configuration must contain exactly one job-specific configuration object (e.g., query, load, extract, spreadsheetExtract), but there were 0:
Please let me know how to use the insert_job method.
I'm not sure what client library you're using, but insert_job probably takes a JobConfiguration. You should create one of those and set the query parameter to equal your JobConfigurationQuery you've created.
This is necessary because you can insert various jobs (load, copy, extract) with different types of configurations to this one API method, and they all take a single configuration type with a subfield that specifies which type and details about the job to insert.
More info from BigQuery's documentation:
jobs.insert documentation
job resource: note the "configuration" field and its "query" subfield