Access any structure field chosen dynamically at run time - field

I have a problem, so I have a huge table where some fields contain only numbers from 1-20 and I want to move the values of the fields to a new table where there are 3 fields with a name and the number (zjdc01 or zadc01).
Now I want to check the field value from the huge table and append the values to the new fields.
For Example :
CASE LS_ATLAS_DC-ZJDC01.
WHEN 1.
LS_ATLAS-ZJDC01 = LS_ATLAS_DC-ZJDC01.
LS_ATLAS-ZADC01 = LS_ATLAS_DC-ZADC01.
LS_ATLAS-ZBDC01 = LS_ATLAS_DC-ZBDC01.
WHEN 2.
LS_ATLAS-ZJDC02 = LS_ATLAS_DC-ZJDC01.
LS_ATLAS-ZADC02 = LS_ATLAS_DC-ZADC01.
LS_ATLAS-ZBDC02 = LS_ATLAS_DC-ZBDC01.
WHEN 3.
LS_ATLAS-ZJDC03 = LS_ATLAS_DC-ZJDC01.
LS_ATLAS-ZADC03 = LS_ATLAS_DC-ZADC01.
LS_ATLAS-ZBDC03 = LS_ATLAS_DC-ZBDC01.
WHEN 4.
LS_ATLAS-ZJDC04 = LS_ATLAS_DC-ZJDC01.
LS_ATLAS-ZADC04 = LS_ATLAS_DC-ZADC01.
LS_ATLAS-ZBDC04 = LS_ATLAS_DC-ZBDC01.
But this is very exhausting and I think there is another Solution but I dont know if ABAP have something for this.
Maybe some of you have a Solution or have a similiar problem which he solved.

Use ASSIGN COMPONENT name OF STRUCTURE structure TO <field_symbol>.
DATA name TYPE string. " component name
FIELD-SYMBOLS: <zjdc_xx> TYPE any,
<zadc_xx> TYPE any,
<zbdc_xx> TYPE any.
IF number BETWEEN 1 and 4.
name = |ZJDC{ number WIDTH = 2 ALIGN = RIGHT PAD = '0' }|. "<== ZJDC01 to ZJDC04
ASSIGN COMPONENT name OF STRUCTURE ls_atlas TO <zjdc_xx>.
name = |ZADC{ number WIDTH = 2 ALIGN = RIGHT PAD = '0' }|. "<== ZADC01 to ZADC04
ASSIGN COMPONENT name OF STRUCTURE ls_atlas TO <zadc_xx>.
name = |ZBDC{ number WIDTH = 2 ALIGN = RIGHT PAD = '0' }|. "<== ZBDC01 to ZBDC04
ASSIGN COMPONENT name OF STRUCTURE ls_atlas TO <zbdc_xx>.
<zjdc_xx> = LS_ATLAS_DC-ZJDC01.
<zadc_xx> = LS_ATLAS_DC-ZADC01.
<zbdc_xx> = LS_ATLAS_DC-ZBDC01.
ENDIF.

Related

Renaming variable with a suffix within an SPSS Macro

I use the following code to winsorize variables in my dataset using SPSS. In the line where it says COMPUTE !var = MAX(MIN(!var, maxval), minval)., I want it to create a new variable with _w as the suffix. Of course, COMPUTE !var_w = MAX(MIN(!var, maxval), minval). will not work. Any solutions, preferably without using Python? Also, is there a way to loop this so that I can include more than one variable when I execute it? For example, !winsor vars = roa, leverage, roe lowpc = 1 hipc = 1..
DEFINE !winsor (var = !TOKENS(1) / lowpc = !TOKENS(1) / hipc = !TOKENS(1))
COMPUTE nobreak=1.
RANK VARIABLES = !var (A) BY nobreak /PERCENT INTO pc_ /PRINT = YES /TIES = MEAN.
XSAVE OUTFILE = 'data.sav'.
SORT CASES BY pc_ (D).
SELECT IF pc_ <= !lowpc.
N OF CASES 1.
RENAME VARIABLE (!var = minval).
SAVE OUTFILE = 'minval.sav' /KEEP = nobreak minval.
GET FILE='data.sav'.
SELECT IF pc_ >= (!hipc).
SORT CASES BY pc_ (A).
N OF CASES 1.
RENAME VARIABLE (!var = maxval).
SAVE OUTFILE = 'maxval.sav' /KEEP = nobreak maxval.
MATCH FILES FILE = 'data.sav'
/TABLE = 'minval.sav'
/TABLE = 'maxval.sav'
/BY = nobreak
/DROP = nobreak.
COMPUTE !var_w = MAX(MIN(!var, maxval), minval).
EXECUTE.
DELETE VARIABLES pc_ minval maxval.
DATASET CLOSE DataSet1.
EXECUTE.
!ENDDEFINE.
!winsor var = roa lowpc = 1 hipc = 1.
In order to add a suffix to your new variable name you need to use the spss macro command !concat like this:
COMPUTE !concat(!var,"_w") = MAX(MIN(!var, maxval), minval).
In order to do this for a list of variables you can use a macro loop:
define macrowithloop(vrs=!cmdend)
!do !vr !in(!vrs)
* do stuff.
COMPUTE !concat(!vr,"_w") = MAX(MIN(!vr, maxval), minval).
* other stuff.
!doend
!enddefine.
macrowithloop vars=roa leverage roe lowpc .

Select particular listbox value on start of Dynpro?

I have a custom dialog dynpro including an input field named DYN_MATNR as listbox for which I have included a list of particular materials as selection.
How can I set a specific material (of that list) as selected when the dialog dynpro is opened?
PBO of dialog dynpro:
data lt_values type vrm_values.
select matnr,
maktx
into table #data(lt_materials)
from makt
where matnr in #so_matnr
and spras = 'D'
order by matnr.
loop at lt_materials assigning field-symbol(<material>).
append initial line to lt_values assigning field-symbol(<value>).
<value>-key = <material>-matnr.
<value>-text = <material>-maktx.
endloop.
call function 'VRM_SET_VALUES'
exporting
id = 'DYN_MATNR'
values = lt_values
exceptions
id_illegal_name = 1
others = 2.
if sy-subrc <> 0.
" ...
endif.
This works and it shows the list of materials as listbox values. To select a particular material I have included the FM DYNP_VALUES_UPDATE afterwards and also in PBO but this did not work:
data lv_stepl type syst-stepl.
call function 'DYNP_GET_STEPL'
importing
povstepl = lv_stepl
exceptions
stepl_not_found = 1
others = 2.
if sy-subrc <> 0.
" ...
endif.
data(lt_dynpfields) = value dynpread_tabtype(
( fieldname = 'DYN_MATNR'
stepl = lv_stepl
fieldvalue = gcl_helper->get_matnr( ) " matnr which should be selected is stored here
fieldinp = space )
).
call function 'DYNP_VALUES_UPDATE'
exporting
dyname = sy-repid
dynumb = sy-dynnr
tables
dynpfields = lt_dynpfields
exceptions
invalid_abapworkarea = 1
invalid_dynprofield = 2
invalid_dynproname = 3
invalid_dynpronummer = 4
invalid_request = 5
no_fielddescription = 6
undefind_error = 7
others = 8.
if sy-subrc <> 0.
" ...
endif.
I am also not able to directly set DYN_MATNR as it is not available in PBO.
Any hints?
Got it:
You need to additionally define a global(!) variable with the name and (wished) type of the input field (e.g. in the top include of the report or in a separate include of the dynpro logic):
data dyn_matnr type matnr.
Then you can set the initial value of the dynpro field in PBO directly:
dyn_matnr = gcl_helper->get_matnr( ).
As this becomes rather irritating when using various dialog dynpros I recommend including the dynpro number in those variables and input fields.

IfcOpenShell(Parse)_IFC PropertySet, printing issue

Hy, I am new to programming and I have problems with printing my property sets and values.
I have more elements in my IFC and want to Parse all Property Sets and values.
My current result is elements ID(for every element), but it takes the attributes(property sets and values) form the first one.
Sketch:
see image
My code:
import ifcopenshell
ifc_file = ifcopenshell.open('D:\PZI_9-1_1441_LIN_CES_1-17c-O_M-M3.ifc')
products = ifc_file.by_type('IFCPROPERTYSET')
for product in products:
print(product.is_a())
print(product) # Prints
Category_Name_1 = ifc_file.by_type('IFCBUILDINGELEMENTPROXY')[0]
for definition in Category_Name_1.IsDefinedBy:
property_set = definition.RelatingPropertyDefinition
headders_list = []
data_list = []
max_len = 0
for property in property_set.HasProperties:
if property.is_a('IfcPropertySingleValue'):
headers = (property.Name)
data= (property.NominalValue.wrappedValue)
#print(headders)
headders_list.append(headers)
if len(headers) > max_len: max_len = len(headers)
#print(data)
data_list.append(data)
if len(data) > max_len: max_len = len(data)
headders_list = [headers.ljust(max_len) for headers in headders_list]
data_list = [data.ljust(max_len) for data in data_list]
print(" ".join(headders_list))
print(" ".join(data_list))
Has somebody a solution?
Thanks and kind regards,
On line:
Category_Name_1 = ifc_file.by_type('IFCBUILDINGELEMENTPROXY')[0]
it seems that you are referring always to the first IfcBuildingElementProxy object (because of the 0-index). The index should be incremented for each product, I guess.

How to parse the config file shown to create a lua table that is desired?

I want to parse a config file which has information like:
[MY_WINDOW_0]
Address = 0xA0B0C0D0
Size = 0x100
Type = cpu0
[MY_WINDOW_1]
Address = 0xB0C0D0A0
Size = 0x200
Type = cpu0
[MY_WINDOW_2]
Address = 0xC0D0A0B0
Size = 0x100
Type = cpu1
into a LUA table as follows
CPU_TRACE_WINDOWS =
{
["cpu0"] = {{address = 0xA0B0C0D0, size = 0x100},{address = 0xB0C0D0A0, size = 0x200},}
["cpu1"] = {{address = 0xC0D0A0B0, size = 0x100},...}
}
I tried my best with some basic LUA string manipulation functions but couldn't get the output that I'm looking for due to repetition of strings in each sections like 'Address',' Size', 'Type' etc. Also my actual config file is huge with 20 such sections.
I got so far, this is basically one section of the code, rest would be just repetition of the logic.
OriginalConfigFile = "test.cfg"
os.execute("cls")
CPU_TRACE_WINDOWS = {}
local bus
for line in io.lines(OriginalConfigFile) do
if string.find(line, "Type") ~= nil then
bus = string.gsub(line, "%a=%a", "")
k,v = string.match(bus, "(%w+) = (%w+)")
table.insert(CPU_TRACE_WINDOWS, v)
end
end
Basically I'm having trouble with coming up with the FINAL TABLE STRUCTURE that I need. v here is the different rvalues of the string "Type". I'm having issues with arranging it in the table. I'm currently working to find a solution but I thought I could ask for help meanwhile.
This should work for you. Just change the filename to wherever you have your config file stored.
f, Address, Size, Type = io.input("configfile"), "", "", ""
CPU_TRACE_WINDOWS = {}
for line in f:lines() do
if line:find("MY_WINDOW") then
Type = ""
Address = ""
Size = ""
elseif line:find("=") then
_G[line:match("^%a+")] = line:match("[%d%a]+$")
if line:match("Type") then
if not CPU_TRACE_WINDOWS[Type] then
CPU_TRACE_WINDOWS[Type] = {}
end
table.insert(CPU_TRACE_WINDOWS[Type], {address = Address, size = Size})
end
end
end
end
It searches for the MY_WINDOW phrase and resets the variable. If the table exists within CPU_TRACE_WINDOWS, then it just appends a new table value, otherwise it just creates it. Note that this is dependent upon Type always being the last entry. If it switches up anywhere, then it will not have all the required information. There may be a cleaner way to do it, but this works (tested on my end).
Edit: Whoops, forgot to change the variables in the middle there if MY_WINDOW matched. That needed to be corrected.
Edit 2: Cleaned up the redundancy with table.insert. Only need it once, just need to make sure the table is created first.

ESQL XML Creation in IIB

Can someone help me in creating the below xml structure using ESQL in IIB
Input:
<animal>
<animaldomestic>dog<animaldomestic>
<animalwild>cheetah<animalwild>
</animal>
Output:
<animals>
<animal type="domestic">cow</animal>
<animal type="wild">cheetah</animal>
</animals>
SET OuputRoot.XMLNSC.animals.(XMLNSC.Attribute)animal = 'domestic';
SET OutputRoot.XMLNSC.animals.animal = 'cow';
SET OuputRoot.XMLNSC.animals.(XMLNSC.Attribute)animal = 'wild';
SET OutputRoot.XMLNSC.animals.animal = 'cheetah';
I found solution for this.Please find the below code:
SET OutputRoot.XMLNSC.animals.animal[1].(XMLNSC.Attribute)type = 'domestic';
SET OutputRoot.XMLNSC.animals.animal[1]VALUE = InputRoot.XMLNSC.animal.animaldomestic;
SET OutputRoot.XMLNSC.animals.animal[2].(XMLNSC.Attribute)type = 'wild';
SET OutputRoot.XMLNSC.animals.animal[2]VALUE = InputRoot.XMLNSC.animal.animalwild;
If you want universal code:
DECLARE animal REFERENCE TO InputRoot.XMLNSC.animal.*[>];
DECLARE type CHAR;
DECLARE I INTEGER 1;
WHILE LASTMOVE(animal) DO
SET type = SUBSTRING(FIELDNAME(animal) AFTER 'animal');
SET OutputRoot.XMLNSC.animals.animal[I] = FIELDVALUE(animal);
SET OutputRoot.XMLNSC.animals.animal[I].(XMLNSC.Attribute)type = type;
SET I = I + 1;
SET type = '';
MOVE animal NEXTSIBLING;
END WHILE;
#Egorka_nazarov's solution is the best. A couple of improvements are possible, though:
FOR refAnimals AS InputRoot.XMLNSC.animal.*[];
CREATE LASTCHILD OF OutputRoot.XMLNSC.animals
AS refNewAnimal
TYPE NameValue
NAME 'animal'
VALUE FIELDVALUE(refAnimals);
DECLARE type CHARACTER SUBSTRING(FIELDNAME(refAnimals) AFTER 'animal');
SET refNewAnimal.(XMLNSC.Attribute)type = type;
END FOR;
The above code is shorter and less likely to contain bugs (once you have practiced with REFERENCE variables, obviously).

Resources