I have a field symbol of a component of a structure:
ASSIGN COMPONENT lv_field_name OF STRUCTURE ls_structure TO <lv_data>.
IF sy-subrc = 0.
WRITE <lv_data> TO lv_field_value.
ENDIF.
Problem: if <lv_data> is of type CURR the result of WRITE... might be wrong.
<lv_data> references to to a field that holds the currency symbol (like 'EUR').
In my case we can make the assumption that the referenced currency field is in the same structure.
Is there an abstract way to get the referenced currency value of <lv_data> so that I can write something like
WRITE <lv_data> TO lv_field_value CURRENCY <lv_currency>.
I looked into class cl_abap_typedescr and subclasses, but I found nothing that I can use to assign <lv_currency>.
The class cl_abap_structdescr has a method get_ddic_field_list which returns a table of structure DFIES. The fields REFTABLE and REFFIELD contain the name of the reference field for the currency or unit for the corresponding field.
DATA(lo_structdescr) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_data( ls_structure ) ).
DATA(lt_ddic_fields) = lo_structdescr->get_ddic_field_list( ).
DATA(ls_ddic_info) = lt_ddic_fields[ fieldname = lv_field_name ].
ASSIGN COMPONENT lv_field_name OF STRUCTURE ls_structure TO FIELD-SYMBOL(<lv_data>).
ASSIGN COMPONENT ls_ddic_info-reffield OF STRUCTURE ls_structure TO FIELD-SYMBOL(<lv_currency>).
WRITE <lv_data> CURRENCY <lv_currency>.
Caveat: This code assumes that the currency field is in the same structure as the value field. This is not always the case! It is possible that ls_ddic_info-reftable mentions a different structure. In that case it gets a lot more complicated. You need to find the entry of that table which corresponds to your structure (probably from the database) and retrieve the currency field from there.
Related
I would like to know if there's an internal function in Erlang, similar to the one posted below, that will give me the record field values instead of the record field names.
record_info(fields, RecordName).
A record in Erlang is really a tuple with it's first element being the name of the record. After compilation is done, the record will be seen as a tuple.
If you have this record definition:
-record(name, [field, anotherfield]).
Then you can define a value of that record type like so:
#name{ field = value1, anotherfield = value2 }.
However, the actual representation for this under the hood is this:
{name, value1, value2}.
Note that the field names are actually gone here.
Now, if you want a list of the values for each field in the record, you can use tuple_to_list:
[name, value1, value2] = tuple_to_list(Record).
So, as jj1bdx pointed out, if you want a ; separated string of all the values, you could do something like this:
string:join([lists:flatten(io_lib:format("~p", [T])) || T <- tl(tuple_to_list(Record))], ";").
This last code snippet is stolen directly from jj1bdx.
Record in record_info(fields, Record) -> [Field] cannot be a variable, because it must be fixed at the compile time.
If you need to handle the elements in a key-value structure dynamically, use maps.
I have a field which value is an array of strings.
Example: Mom, dad, son, etc.
It is possible to repeat a link with those values?
Example:
Mom
dad
son
And when I click on the link to have a href=www."fieldvalue".com.
EDIT: it is not vector, it is Array.
Create your repeat control. For the value add in your field name. Something like :
document1.getItemValue("myMultiValueField")
I THINK that should repeat your field assuming it is a real multi-value. The comma deliminated string would require more work. So I'm not talking about that...
Make sure the collection name / var name of the repeat is something like "rowData"
rowData should then be a String.
Drop a link control inside the repeat.
Compute the label to be simple "rowData". (no quotes in the code)
Compute the URL - which I THINK is "value" in all properties of the link
That's just javaScript so you should be able to do something like:
return "http://" + rowData + ".com"
That's rough - you'll have to play with it but if I follow you correctly should work.
For a comma deliminated String... in the repeat control you'd need to use SSJS or #functions to break that into an array so the repeat can work on it.
In your repeat you'll need to map the value attribute to the Vector and set a var property, which is how you will reference each element. Note: a comma-separated string is a single value, and a repeat requires multiple values. So you'll need to convert it to a Vector or some other multi-value object.
Within the repeat you can use any other control and compute the value as you would elsewhere. To access each element in your repeat control's source (i.e. each String in your Vector, in this case), use the variable name you've defined in the var property.
In the examples I've checked, the operand is always a primitive value, like:
http://host/service/Products?$filter=MainIngredient eq 'Milk'
what if the MainIngredient property is an entity, and I want to reference exactly this entity? Abstracting other cases, that would be something like
http://host/service/Products?$filter=MainIngredient eq Ingredient('770d5720-9ae8-11e3-a5e2-0800200c9a66)
...or isn't the filter not the correct instrument to use, at all?
I think you mean that MainIngredient is the name of a navigation property that points to a single entity of type Ingredient, such as:
http://host/service/Products(1234)/MainIngredient
If this is the case, and assuming that the key of Ingredient is called "ID" then I think the correct form of URL for what you want to do is:
http://host/service/Products?$filter=MainIngredient/ID eq guid'770d5720-9ae8-11e3-a5e2-0800200c9a66'
That would return only products that are linked, via MainIngredient, to the Ingredient with the ID you gave in the question.
I want to know the difference between following two statements related to datasets in delphi.
dsMyDataSet.ParamByName('ID').AsInteger := 1122; //If ID is integer
dsMyDataSet.ParamByName('ID').AsString := '1122'; //If ID is string
and
dsMyDataSet.ParamByName('ID').Value := 1122; //ID is string or integer
Do these statements carry same meaning? Does "value" implicitly converts integer into string?
The TParam.AsInteger property, for instance, set the value and the data type of the parameter. TParam.Value does the same, but TParam will decide which type will be mapped to the value inside the Variant and not always it´s the data type you would like.
I advise you to set values by using the AsXXX properties only, since you will be in control of the parameter's data type, what can save you from having parameter binding errors.
So, answering your final question: no, the values won´t be converted to the right data type, you have to set the data type by selecting the right property to assign the value.
I have heard that specifying records through tuples in the code is a bad practice: I should always use record fields (#record_name{record_field = something}) instead of plain tuples {record_name, value1, value2, something}.
But how do I match the record against an ETS table? If I have a table with records, I can only match with the following:
ets:match(Table, {$1,$2,$3,something}
It is obvious that once I add some new fields to the record definition this pattern match will stop working.
Instead, I would like to use something like this:
ets:match(Table, #record_name{record_field=something})
Unfortunately, it returns an empty list.
The cause of your problem is what the unspecified fields are set to when you do a #record_name{record_field=something}. This is the syntax for creating a record, here you are creating a record/tuple which ETS will interpret as a pattern. When you create a record then all the unspecified fields will get their default values, either ones defined in the record definition or the default default value undefined.
So if you want to give fields specific values then you must explicitly do this in the record, for example #record_name{f1='$1',f2='$2',record_field=something}. Often when using records and ets you want to set all the unspecified fields to '_', the "don't care variable" for ets matching. There is a special syntax for this using the special, and otherwise illegal, field name _. For example #record_name{record_field=something,_='_'}.
Note that in your example you have set the the record name element in the tuple to '$1'. The tuple representing a record always has the record name as the first element. This means that when you create the ets table you should set the key position with {keypos,Pos} to something other than the default 1 otherwise there won't be any indexing and worse if you have a table of type 'set' or 'ordered_set' you will only get 1 element in the table. To get the index of a record field you can use the syntax #Record.Field, in your example #record_name.record_field.
Try using
ets:match(Table, #record_name{record_field=something, _='_'})
See this for explanation.
Format you are looking for is #record_name{record_field=something, _ = '_'}
http://www.erlang.org/doc/man/ets.html#match-2
http://www.erlang.org/doc/programming_examples/records.html (see 1.3 Creating a record)