Generate random GUID - primary-key

I want to generate a random UUID like in Java with UUID.randomUUID().
I came up with the function GUID_GENERATE and used it like this
DO 5 TIMES.
CALL FUNCTION 'GUID_CREATE'
IMPORTING
ev_guid_16 = ev_guid_16
ev_guid_22 = ev_guid_22
ev_guid_32 = ev_guid_32.
WRITE: /, ev_guid_16, ev_guid_22, ev_guid_32.
ENDDO.
The result of this program is always the same GUID. I need a new random one at every request.
I want to use it as a primary key in database table. This key will be transmitted via a Web Service to a Java application and user there as identifier, too.
Do you have any ideas how I can generate random UUID/GUID in ABAP?

First of all you are using a function module that is obsolete. The comment at the beginning of the source code states that.
*"----------------------------------------------------------------------
* NOW this function has been replaced, see note 935047 "BINK215094
* 28.6.2006 The function module has been switched to the new UUID methods
* which exist in the class cl_system_uuid
* - due to compatibility reasons we catch the exceptions
* - sy-subrc not touched manually
* (sy-subrc was set in case of an error when calling the former
* 'RFCControl' kernel-call, but it wasn't evaluated and finally
* overwritten when leaving this function)
*"----------------------------------------------------------------------
Please use class CL_SYSTEM_UUID and the following methods:
IF_SYSTEM_UUID_STATIC~CREATE_UUID_X16
IF_SYSTEM_UUID_STATIC~CREATE_UUID_C22
IF_SYSTEM_UUID_STATIC~CREATE_UUID_C26
IF_SYSTEM_UUID_STATIC~CREATE_UUID_C32

Are you absolutely sure the created GUID is always the same? Because this shouldn't be happening. Note that the difference between them can be just one character when you generate them inside a fast loop.

Related

loading values from `require(file)` into local variables

Sorry if this is an FAQ but if some lib.lua returns a table of local functions e.g.
return {readCsv=readCsv, sumList=sumList, printHelp=printHelp}
and file2.lua imports it using
local lib=require("lib")
is there some programmatic way to automate the loading of the lib values into the local space? So i DON'T have to keep doing e.g.
local readCsv,sumList,printHelp=lib.readCsv,lib.sumList,lib.printHelp
I know its standard practice in LUA and it properly does not annoy many people. But it happens so often that I was wondering if there was a standard shortcut.
(Note: Just to be clear, I know how to make them globals by loading them into _ENV but that is exactly what I do not want.)
In Lua, local variables are statically declared constructs. They're known at compile-time and cannot (generally) be allocated at runtime. Even the number of locals that an individual function holds is known at compile-time, even if the values held in them are not known until the function object is created.
As such, there is no dynamic mechanism to dump the contents of a table into a runtime-defined number of local variables.
The closest you could do is to parse the Lua script text manually to find all of the require statements, do those require yourself, and parse the tables to generate a sequence of local declarations that you will insert into the appropriate place in your Lua script text. You would then compile that script and use it.
But this is a huge amount of work just to get rid of lib.. It's just not worth it.
Since, it's just a regular table that is being returned by require, you can "unpack" that table to turn it into a list of values:
-- return values as both array and hash
return {readCsv, sumList, printHelp,
readCsv=readCsv, sumList=sumList, printHelp=printHelp}
-- then do
local readCsv,sumList,printHelp = (table.unpack or unpack)(require "lib")
The order of returned/assigned values will obviously matter.
If somebody still wants to use a "regular" syntax with local lib = require "lib", it will continue to work.
Based on the above, I came up with a function that simplifies importing. Now I sort of agree with #NicolBolas that is all a little "cancer of the semi-colon" but heh, its short and optional (only a few lines of code, does not mess with usual LUA module conventions)
get"file" requires the file and unpacks results in alphabetical order. Kind of analogous to the Python command
from file import *
get"file thing1 thing2.." requires the file and unpacks only thing1 thing2. Kind of analogous to the Python command
from file import thing1,thing2
e.g. heres a file that returns some code:
-- file = cc.lua
function fun1() print(1) end
function fun2() print(2) end
function fun3() print(3) end
function fun4() print(4) end
function fun5() print(5) end
return {fun3=fun3, fun1=fun1, fun2=fun2, funs5=fun5, fun4=fun4}
Here's one example of usage (unpack all). Note that the sub-module (cc.lua) can return its things in any order at all and this code will unpack them in alpha order:
-- file = gettest1.lua
local get=require"get"
local fun1,fun2,fun3,fun4,fun5=get"cc"
fun5()
And here's the other usage where we can unpack somethings, in any order we want:
-- file = gettest2.lua
local get=require"get"
local fun3,fun1=get"cc fun3 fun1"
fun1()
And here's the code for the get.lua file that holds the get function
-- file = get.lua
local function get(spec)
local gets, keys,out={},{},{}
for get in string.gmatch(spec, "([^ ]+)") do gets[#gets+1]= get end
local results = require(table.remove(gets,1))
if #gets>0
then keys= gets
else for key,_ in pairs(results) do keys[#keys+1] = key end
table.sort(keys)
end
for _,key in ipairs(keys) do out[#out+1] = results[key] end
return table.unpack(out)
end
return get
Improvements? Suggestions? Comments?

AS400 RPGLE/free dynamic variables in operations

I'm fairly certain after years of searching that this is not possible, but I'll ask anyway.
The question is whether it's possible to use a dynamic variable in an operation when you don't know the field name. For example, I have a data structure that contains a few hundred fields. The operator selects one of those fields and the program needs to know what data resides in the field from the data structure passed. So we'll say that there are 100 fields, and field50 is what the operator chose to operate on. The program would be passed in the field name (i.e. field50) in the FLDNAM variable. The program would read something like this the normal way:
/free
if field50 = 'XXX'
// do something
endif;
/end-free
The problem is that I would have to code this 100 times for every operation. For example:
/free
if fldnam = 'field1';
// do something
elseif fldnam = 'field2';
// do something
..
elseif fldnam = 'field50';
// do something
endif;
Is there any possible way of performing an operation on a field not yet known? (i.e. IF FLDNAM(pointer data) = 'XXX' then do something)
If the data structure is externally-described and you know what file it comes from, you could use the QUSLFLD API to find out the offset, length, and type of the field in the data structure, and then use substring to get the data and then use other calculations to get the value, depending on the data type.
Simple answer, no.
RPG's simply not designed for that. Few languages are.
You may want to look at scripting languages. Perl for instance, can evaluate on the fly. REXX, which comes installed on the IBM i, has an INTERPRET keyword.
REXX Reference manual

Generation of ABAP report in runtime possible?

Is there any Function module that can generate ABAP code.
For eg: FM takes tables name and join conditions as input and generate ABAP code corresponding to that.
Thanks
You should consider using SAPQuery. SAP documentation here: https://help.sap.com/saphelp_erp60_sp/helpdata/en/d2/cb3efb455611d189710000e8322d00/content.htm
1. Generic reports are possible.
Your problem is, that You will have to draw a strict frame of what is
generic and what not, this means, some stuff MUST be that generic, that
it will deal with WHATEVER You want to do before ( mostly the selection ) ,
during ( mostly manipulation ---> I would offer a badi for that ), and output.
This means, that there is at least the output-step, which can be valid for ALL
data resulting from the steps before.
Consider a generic ALV-table_output, there are a lot of examples in the repo.
If You want to be the stuff printed out simple as list, this might include
more work, like, how big is the structure, when Dou You wrap a line, and so on, consider using a flag which allows to toggle the type of output .
2. Generic reports are a transportable object.
This refers to point one. Define clear stages and limits. What does the report do, and what is it not able to do. Because, even if it is in customer's namespace, each modification still will be put into transport-layers. Therefore a strict definition of features/limits is necessary so that the amount of transports due to "oh, but we also need that"-statements will not become infinite.
2. Generic reports are strict.
What does that mean ? You might want to parse the passed data ( table names, join-binding, selection-parameter-values ) and throw exceptions, if not properly set. Much work. You should offer a badi for that. If You do not do this, expect a dump. let it dump. In the end the user of Your report-api should know ( by documentation perhaps) how to call it. If not, a dynamic SQL-dump will be the result.
3. Generic reports might benefit from badis/exits.
This is self explanaining, I think. Especially generic/dynamic selection/modification/displaying of data should be extendable in terms of
custom-modifications. When You inspect, what a f4-search-help exit works like, You will understand, what I mean.
4. Generic coding is hard to debug, mostly a blackbox.
Self explaining, in the code-section below I can mark some of those sections.
5. Generic coding has some best prectice examples in the repo.
Do not reinvent the wheel. Check, how the se16n works by debugging it,
check how se11 works by debugging it. Check, what the SQL-Query-builder
looks like in the debugger. You will get the idea very soon,
and the copy-paste should be the most simple part of Your work.
6. That are the basic parts of what You might use.
Where clause determination and setting the params.
data lt_range type rsds_trange.
data ls_range_f type rsds_frange.
data lt_where type rsds_twhere.
data ls_where like line of lt_where.
ls_range_f = value #( sign = _sign
option = _option
low = _low
high = _high ).
.
.
.
append ls_frange to lt_range.
.
.
.
call function 'FREE_SELECTIONS_RANGE_2_WHERE'
exporting
field_ranges = lt_range
importing
where_clauses = lt_where.
You have the parameter, let us create the select-result-table.
data(lt_key) = value abap_keydescr_tab( for line in _joinfields)
( name = fieldname ) ).
data(lo_structdescr) = cast cl_abap_structdescr( cl_abap_structdescr=>describe_by_name( _struct_name ) ).
data(lo_tabledescr) = cl_abap_tabledescr=>create( line_type = lo_structdescr p_key = lt_key ).
create data ro_data type handle lo_tabledescr.
.
.
.
select (sel_st)
from (sel_bind)
into corresponding fields of table t_data
where (dyn_where).
Then assign the seelct-table-result-reference to the generic table of this select.
Do You need more hints ?
Yes, such possibility exists, but not by means of function modules. INSERT REPORT statement allows generating report by populating its code from internal text table:
INSERT REPORT prog FROM itab
[MAXIMUM WIDTH INTO wid]
{ [KEEPING DIRECTORY ENTRY]
| { [PROGRAM TYPE pt]
[FIXED-POINT ARITHMETIC fp]
[UNICODE ENABLING uc] }
| [DIRECTORY ENTRY dir] }.

Get Text Symbol Programmatically With ID

Is there any way of programmatically getting the value of a Text Symbol at runtime?
The scenario is that I have a simple report that calls a function module. I receive an exported parameter in variable LV_MSG of type CHAR1. This indicates a certain status message created in the program, for instance F (Fail), X (Match) or E (Error). I currently use a CASE statement to switch on LV_MSG and fill another variable with a short description of the message. These descriptions are maintained as text symbols that I retrieve at compile time with text-MS# where # is the same as the possible returns of LV_MSG, for instance text-MSX has the value "Exact Match Found".
Now it seems to me that the entire CASE statement is unnecessary as I could just assign to my description variable the value of the text symbol with ID 'MS' + LV_MSG (pseudocode, would use CONCATENATE). Now my issue is how I can find a text symbol based on the String representation of its ID at runtime. Is this even possible?
If it is, my code would look cleaner and I wouldn't have to update my actual code when new messages are added in the function module, as I would simply have to add a new text symbol. But would this approach be any faster or would it in fact degrade the report's performance?
Personally, I would probably define a domain and use the fixed values of the domain to represent the values. This way, you would even get around the string concatenation. You can use the function module DD_DOMVALUE_TEXT_GET to easily access the language-dependent text of a domain value.
To access the text elements of a program, use a function module like READ_TEXT_ELEMENTS.
Be aware that generic programming like this will definitely slow down your program. Whether it would make your code look cleaner is in the eye of the beholder - if the values change rarely, I don't see why a simple CASE statement should be inferior to some generic text access.
Hope I understand you correctly but here goes. This is possible with a little trickery, all the text symbols in a report are defined as variables in the program (with the name text-abc where abc is the text ID). So you can use the following:
data: lt_all_text type standard table of textpool with default key,
lsr_text type ref to textpool.
"Load texts - you will only want to do this once
read textpool sy-repid into lt_all_text language sy-langu.
sort lt_all_Text by entry.
"Find a text, the field KEY is the text ID without TEXT-
read table lt_all_text with key entry = i_wanted_text
reference into lsr_text binary search.
If you want the address you can add:
field-symbols: <l_text> type any.
data l_name type string.
data lr_address type ref to data.
concatenate 'TEXT-' lsr_text->key into l_name.
assign (l_name) to <l_text>.
if sy-subrc = 0.
get reference of <l_text> into lr_address.
endif.
As vwegert pointed out this is probably not the best solution, for error handling rather use message classes or exception objects. This is useful in other cases though so now you know how.

calling script_execute with a variable

I'm using GameMaker:Studio Pro and trying to execute a script stored in a variable as below:
script = close_dialog;
script_execute(script);
It doesn't work. It's obviously looking for a script named "script". Anyone know how I can accomplish this?
This question's quite old now, but in case anyone else ends up here via google (as I did), here's something I found that worked quite well and avoids the need for any extra data structures as reference:
scriptToCall = asset_get_index(scr_scriptName);
script_execute(scriptToCall);
The first line here creates the variable scriptToCall and then assigns to it Game Maker's internal ID number for the script you want to call. This allows script_execute to correctly find the script from the ID, which doesn't work if you try to pass it a string containing the script name.
I'm using this to define which scripts should be called in a particular situation from an included txt file, hence the need to convert a string into an addressable script ID!
You seem to have some confusion over how Game Maker works, so I will try to address this before I get around to the actual question.
GML is a rather simple-minded beast, it only knows two data types: strings and numbers. Everything else (objects, sprites, scripts, data structures, instances and so on) is represented with a number in your GML code.
For example, you might have an object called "Player" which has all kinds of fancy events, but to the code Player is just a constant number which you can (e.g.) print out with show_message(string(Player));
Now, the function script_execute(script) takes as argument the ID of the script that should be executed. That ID is just a normal number. script_execute will find the script with that ID in some internal table and then run the script.
In other words, instead of calling script_execute(close_dialog) you could just as well call script_execute(14) if you happened to know that the ID of close_dialog is 14 (although that is bad practice, since it make the code difficult to understand and brittle against ID changes).
Now it should be obvious that assigning the numeric value of close_dialog to a variable first and then calling script_execute on that variable is perfectly OK. In the end, script_execute only cares about the number that is passed, not about the name of the variable that this number comes from.
If you are thinking ahead a bit, you might wonder whether you need script_execute at all then, or if you could instead just do this:
script = close_dialog;
script();
In my opinion, it would be perfectly fine to allow this in the language, but it does not work - the function call operator actually does care about the name of the thing you try to call.
Now with that background out of the way, on to your actual question. If close_dialog is actually a script, your suggested code will work fine. If it is an extension function (or a built-in function -- I don't own Studio so what do I know) then it does not actually have an ID, and you can't call it with script_execute. In fact, you can't even assign close_dialog to a variable then because it does not have any value in GML -- all you can do with it then is call it. To work around this though, you could create a script (say, close_dialog_script which only calls close_dialog, which you can then use just as above.
Edit: Since it does not seem to work anyway, check whether you have a different resource by the name of close_dialog (perhaps a button sprite). This kind of conflict could mean that close_dialog gives you the ID of the sprite, not of the script, while calling the script directly would still work.
After much discussion on the forums, I ended up going with this method.
I wrote a script called script_id()
var sid;
sid = 6; //6 = scriptnotfound script :)
switch (argument0) {
case "load_room":
sid = 0;
break;
case "show_dialog":
sid = 1;
break;
case "close_dialog":
sid = 3;
break;
case "scrExample":
sid = 4;
break;
}
return sid;
So now I can call script_execute(script_id("close_dialog"));
I hate it, but it's better than keeping a spreadsheet... in my opinion.
There's also another way, with execute_string();
Should look like this:
execute_string(string(scriptName) + "();");