2009 Oct 06 2:52 PM
I have a persistent object that has the attributes:
Key1
Key2
Key_EffectiveDate
NonKey1
NonKey2
NonKey3
...
NonKeyn
I'd like to make a persistent copy of an object of this class, changing only the (key) effective date,
and retaining all the non key values.
Is there an easy way to do this?
I do not want to run a method that needs to have all the non-key attributes passed to it.
Rather, I want to run something that looks like
=>createPersistentCopy( OldKey = ... .. .
NewKey = ... .. .
returning newObjectRef )
( This is for an app we are creating that uses date delimited objects)
Thanks...
...Mike
2009 Oct 08 2:36 PM
just in case, if you do not want to work with the structure name as in the above example, you can also use the class CL_ABAP_OBJECTDESCR and its method DESCRIBE_BY_OBJECT_REF. The resulting object will have an attribute ATTRIBUTES, which is an internal table, that holds all the information about the attributes of the object reference you've passed to DESCRIBE_BY_OBJECT_REF.
best regards,
Hans Hohenfeld
2009 Oct 06 3:20 PM
Hi,
I'm not entirely sure which way to solve this you prefer. I would add an instance method to the persistence class, which copies the object with the changed key, i.e.
method copy_me importing i_new_key type ...
returning value(r_copy) type ref to ZCL_Pers_class.
data: lo_copy type ref to zcl_pers_class.
lo_copy = zca_pers_class=>agent->create_persistent( i_key1 = me->key1
i_key2 = me->key2
i_key3 = i_new_key ).
lo_copy->set_field1( me->field1 ).
....
r_copy = lo_copy.
endmethod.of course with some error handling, but I guess you'll get that right yourself
If the persitence class has lots of fields, and you are to lazy to type/c&p, you can fill the copied object, by looping over all non key fields and building tzhe setter methody dynamically (use cl_abap_structdescr for that)
best regards,
Hans Hohenfeld
2009 Oct 06 6:48 PM
Its not a matter of not wanting to code/copy all the setters in.
I just think it is bad form to create a method that would need maintenance if/when the underlying attributes are changed.
In the absence of a canned soultion, we had thought of a solution similar to what you suggest. I had considered implementing an interface within our application that has a copy_with_new_date method.
We could loop through the keyed attributes, overwriting the begda to create the new objects, and...
loop through the non keyed attributes to copy the additional values.
That works.
I am not very familiar with the CL_ABAP_xxxDESCR classes .
How, given a class such as ZCL_MYWIDGET, or local object, lo_widget, does one return the list of attrbutes. I've tried a number of combinations, but can't figure it out.
...Mike
( By the way, our object has both persistent and non-persitent values)
2009 Oct 07 2:58 PM
Hi,
if you do not want to change the method every time, the persitence class' attributes change, use CL_ABAP:STRUCTDESCR as follows:
data: lo_descr type ref to cl_abap_structdescr,
lo_type type ref to cl_abap_elemdescr.
data: lt_params type abap_parmbind_tab,
ls_param type abap_parmbind.
data: l_method type string,
l_param type string,
l_type type string.
field-symbols: <ls_component> type abap_compdescr,
<l_comp> type any,.
" use the name of the table/view/structure corresponding to your persistence class here
lo_descr ?= cl_abap_structdescr=>describe_by_name( 'NAME_OF_STRUCTURE' ).
loop at lo_descr->components assigning <ls_component> where name <> .... "fields you do not want
" to copy
assign me->(<ls_component-name>) to <l_comp>.
if sy-subrc = 0.
" get type of the attribute
lo_type ?= cl_abap_elemdescr=>describe_by_data( <l_comp> ).
l_type = lo_type->get_relative_name( ).
" build method and parameter
concatenate 'SET_' <ls_struct_comp>-name into l_method.
concatenate 'I_' <ls_struct_comp>-name into l_param.
" build parameter table for dynamic method call
create data ls_param-value type (l_type).
get reference of <l_comp> into ls_param-value.
ls_param-name = l_param.
insert ls_param into table lt_params.
" call setter method of coppied object dynamically
try .
call method lo_copy->(l_method)
parameter-table
lt_params.
catch cx_root.
" handle errors somehow
endtry.
endif.
refresh lt_params.
clear ls_param.
endloop.It might seem a bit complex at first sight, but works like a charme. I created a class in the system which holds some helper methods, I can reuse to fill a persistence object from a filled structure or fill a structure from the persistence object and so on...
best regards,
Hans Hohenfeld
2009 Oct 08 2:36 PM
just in case, if you do not want to work with the structure name as in the above example, you can also use the class CL_ABAP_OBJECTDESCR and its method DESCRIBE_BY_OBJECT_REF. The resulting object will have an attribute ATTRIBUTES, which is an internal table, that holds all the information about the attributes of the object reference you've passed to DESCRIBE_BY_OBJECT_REF.
best regards,
Hans Hohenfeld
2009 Oct 08 3:29 PM
Thank you Hans.
Your answers have been appreciated. The last part about cl_abap_objectdescr=>describe_by_object_ref was quite helpful, as I needed to go after the attributes specifically.
Thanks...
...Mike McInerney