Is there an Object-Oriented way to use standard reporting events? - abap

Is there an Object-Oriented way to create functionality for the standard reporting events like INITIALIZATION or AT SELECTION-SCREEN?

As far as I am aware, there isn't an object-oriented alternative to the classic reporting events.
What I usually do when I am in an object-oriented mood but want to create a classic report with selection screen is to create a local class lcl_main and then write code like this:
INITIALIZATZION.
lcl_main=>initialization(
CHANGING cv_date = p_date
ct_bukrs = s_bukrs[] ).
AT SELECTION-SCREEN OUTPUT.
lcl_main=>at_selection_screen_output(
CHANGING cv_date = p_date
ct_bukrs = s_bukrs[] ).
START-OF-SELECTION.
lcl_main=>start_of_selection(
iv_date = p_date
it_bukrs = s_bukrs[] ).
This is also what the most recent version of the official SAP documentation for START-OF-SELECTION does.

Related

Documentation about functions used in SSRS

I will keep it as short as possible. ( Please take into consideration , that I am not familiar with c# programming / dll and such things. I have been mostly working in the Data Analysis world with python )
I have a report in SSRS in Visual Studio that I would like to add some embedded code.
And i am trying to call those functions that are available for the SSRS
Microsoft Documentation states that for those functions you could call them by given the specific class.
for example
Math.Floor()
https://learn.microsoft.com/en-us/sql/reporting-services/report-design/custom-code-and-assembly-references-in-expressions-in-report-designer-ssrs?view=sql-server-ver15
. For convenience, you can view the most commonly used functions in the Expression dialog box, where they are listed by category: Text, Date and Time, Math, Inspection, Program Flow, Aggregate, Financial, Conversion, and Miscellaneous. Less commonly used functions do not appear in the list but can still be used in an expression.
I am trying to use the lookup function in the code
by calling Miscellaneous.Lookup
but somehow I get an error that this class does not exist.
do you have any idea where is the API/DEV Documentation related to this. I cannot really find any documentation reference to that function.
If I try with Math.Floor(1) it actually works
another a little bit more complex code
public function a(byVal x as Integer) as String
if(x = 1 ) then
Return Math.Floor(1)
else Return 2
end if
end function
EDIT: ( Thanks #Timothy G. )
Miscellaneous.Lookup(1,1,"holaInLookup","DataSet1")
Still same error

Is there anything like type inference in Apex?

Working my way through Salesforce Trailhead code modules feels like stepping back in time (having spent the last few years working in c# and JavaScript), is there anything (a tool or modern compiler/runtime) that can infer type specifically for things like for loops like this?
List<Account> accs = [SELECT Id, Name FROM Account WHERE Name = 'Siebel'];
for(Account a : accs){
a.Name = 'Oracle';
}
You can look at the generic SObject class SObjectType class and getDescribe() calls. Also looking at Dynamic Apex might get you closer to what you are looking for. But still there are alot of limitation with the language.

Unable to access RTTI for SmartMobileStudio

Trying to use Smart's RTTI as defined in this post, I was not able to let RTTI be emitted to the HTML.
When I define:
type
TBase = class
published
Field : Integer = 1;
end;
var base := new TBase;
PrintPropertiesForType(base);
Then, there is no RTTI available for this class.
In index.html, I have:
var $RTTI = [];
Meaning that there is no RTTI emitted.
This occurs for whatever Project Options I have set. (in short, the RTTI compilation option does not make any difference)
I’m using SMS 2.0.1.741.
I’m stuck with implementing a native SMS client for mORMot..
There seem to be a bug with this issue in the latest hotfix. I have reported the issue to the developer team and it should be fixed shortly. I noticed the exact same thing myself testing the RTTI methods on different versions of SMS.
An immediate solution is to just roll-back to version 2.0.0.723.
You can download that version here:
http://smartmobilestudio.com/download/v2_0_0_723/
I found out that it works in the main unit (TApplication) but not in other referenced units. So you can try that in the mean time
As an alternative to automatic persistence (since RTTI is not working in the latest hotfix and you have opted not to use RTTI for object mapping), it should be mentioned that Smart Pascal supports JavaScript structures. This will greatly simplify object storage. If you have ever used a Microsoft property-bag (com class) then this is more or less the same thing.
In JavaScript you would write:
var mbag = {};
mbag["test"] = {};
mbag["test"]["somevalue"] = 12;
mBag["text"] = "this is a string value";
Resulting in a memory structure like this:
Type
TMyBagContent = Record
bcTest = Record
bcSomeValue:Integer;
end;
bcText:String;
End;
In Delphi these kind of structures are implemented in SuperObject (I believe). RemObjects also have some support classes that mimic this. But thankfully Smart Pascal achieves this automatically by grace of targeting JavaScript directly.
So in Smart Pascal you would do the following to achieve the same results:
var mBag:Variant;
mBag:=TVariant.CreateObject;
mBag['test'] := TVariant.CreateObject;
mBag['test']['somevalue']:=12;
mBag['text']:='this is a string';
You can also save some time and use an assembly section:
var mBag:variant;
asm
#mbag = {};
#mbag["test"] = {};
#mbag["test"]["somevalue"] = 12;
#mbag["text"] = "this is a string value";
end;
Once you have populated your object's data, you then use JSON to serialize and make it portable:
var mObj: String;
asm
#mObj = JSON.stringify(#mbag);
end;
Creating reader/writer class for storage is very easy. Naturally automatic RTTI property mapping is better (and that should be fixed shortly), but for frameworks that does it manually - which does have some advantages over full automation - there are plenty of options for creative programmers such as yourself.
There is also speed to consider, and using a JavaScript object as a lookup table is very, very fast compared to a for/next recursive algorithm. Especially for large and complex data structures.
Looking forward to testing your creation :)

C#'s 'dynamic' in F#

One example of using the DLR in C# is as follows:
dynamic dyn = new MyObject();
dyn.MyMethod(); //resolved at runtime
what would be the equivalent in F#?
Thanks.
The ? operator has similar expressive power to the dynamic keyword in C# (but it can be only used for reading of properties, method invocation and setting of properties).
There is no built-in implementation that would allow you to dynamically use properties or methods of a .NET class (via Reflection or DLR), but there are some fairly solid implementations from the community. This has been discussed in another SO question before.
There are also implementations of ? that allow you access some common data sources such as SQL databases. For example, this MSDN article includes a definition that allows you to write db?Query?Foo(1) to call a stored procedure named Foo.
For various other types (such as finding an element in XAML or accessing elements or attributes in XML document), the definition of ? is quite easy to write.
On the flip side, if you're trying to expose dynamic behavior to C# from F#, you can use DynamicAttribute[MSDN]. For example, declaring a dynamic property might look like
type HasDynamicProperty() =
[<Dynamic([|true|])>]
member this.DynamicObject : obj = ...
which is used from C# like
var hdp = new HasDynamicProperty();
dynamic dynObj = hdp.DynamicObject;
There's a package called FSharp.Interop.Dynamic and that will make it possible to do a call to a dynamic object using the ? operator.
F# has the ? operator which you use like so:
myVariable?SomePropertyThatIsNotDeclared
There is no dynamic keyword equivalent. Take a look at this article for how to use it https://weblogs.asp.net/podwysocki/using-and-abusing-the-f-dynamic-lookup-operator

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.