Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Export deep structure to shared memory

Former Member
0 Kudos

Hi Experts,

I am trying to export a deep structure (internal table that itself contains a structure) to shared memory and read the data from another program (different user session). Reading the online help, it seems that statement "Export to database" should be able to handle to export such deep structures but I get an error message saying "In EXPORT/IMPORT and ASSERT...FIELDS, "LS_IL_DATA" cannot be a reference or contain references"

The internal table looks similar to this:

HEADER_GUID CRMT_OBJECT_GUID

HEADER_STRUC_NAME TYPENAME

ITEM_STRUC_NAME TYPENAME

DATA DATA

ITEMS Z_ACTION_INTLAY_ITEM_DATA_T (structure containing items)

Here is the code:

  
data: wa_indx type indx.

data: ls_il_data type z_action_intlay_data (own created structure in SE11)

wa_indx-aedat = sy-datum.
wa_indx-usera = sy-uname.
wa_indx-pgmid = sy-repid.

* Filling LS_IL_DATA with information
.....


export LS_IL_DATA from LS_IL_DATA 
to database indx(za) from wa_index
id 'Z_CONTR_CHNG'.

It seems to work when using a normal structure so why can't I use a deep structure

Do you have any idea why I get this error message stated above?

Edited by: Andreas H on Mar 14, 2011 2:15 PM

12 REPLIES 12

Former Member
0 Kudos

For shared objects, I adapted a how-to presentation from ABAP Object manual...and I do code below. Perhaps you have a syntax problem?

ICL_TAB is: class-data icl_tab type table of iclclaim.


data:  ziclindx_wa type ziclindx,  "type of INDX-LIKE table
         icl_id      type indx-srtfd,
         subrc       type sy-subrc.
* fill ICL_TAB from ICLCLAIM
* store it in INDX-like table.
concatenate 'ICL_CLAIM' sy-datum into icl_id.
 delete from database ziclindx(dl) id icl_id. "if already exists
      ziclindx_wa-aedat = sy-datum.
      ziclindx_wa-aetim = sy-uzeit.
 export icl_claim_tab = icl_tab
              to database ziclindx(dl)   "INDX-like table
              id icl_id
            from ziclindx_wa.

former_member438956
Active Participant
0 Kudos

Hi,

Instead of using IMPORT/EXPORT statements I recommend u to go with static class method as it is the shared memory allocated to the static method and attribute u define for the class...

Make a class called ZCL_STATIC_CLASS in SE24

Add a static attribute to the class called gs_il_data TYPE z_action_intlay_data in the static class.

Create two methods namely SET_DATA and GET_DATA with approprate importing and exporting variables.

1. Method SET_DATA IMPORTINg it_il_data type z_action_intlay_data.

Write code in method as gs_il_data = it_il_data.

This will export ur deep structure to static memory of the class.

Now create GET_DATA method of the same class with parameters as et_il_data type z_action_intlay_data.

wrie code as et_il_data = gs_il_data.

Now use the SET_DATA method in the main program and GET_DATA method in another program.

Hope it will help u.

Regards,

Anil N.

0 Kudos

Hi Anil,

Thanks for a very good suggestion. But when I try it it does not work.

I created the class just as per your description (static attribute and static methods). I also added the "Shared memory enabled" flag on class properties.

But when I try to read the data by calling get_data method in a different program (different user session), gs_il_data contain no data at all.

Is there anything else I need to do?

0 Kudos

Hi Andreas

Hope you are also using the Hanlder clause while instantiating the class reference. Like,


CREATE OBJECT obj AREA HANDLE hdl

You can refer to f1 help on AREA HANDLE usage for better understanding.

Regards

Ranganath

Edited by: Ranganath Ramesh on Mar 14, 2011 3:19 PM

0 Kudos

This message was moderated.

0 Kudos

Hi Andreas,

my 2 cents:

The static class with get/set method is useful only in the current work process. So this approach can be used only if the data are used in the same process.

The documentation about shared-memory data export to INDX-like data objects does not say explicitly that deep structures are not allowed, but they refer to relational database structures a couple of times, so thia may be implicit.

The alternative, Shared objects, is a bit complicated. The chapter about Shared objects in Rich Heilmans book "Next Generation ABAP" is free for download on SAPpress.

Briefly: You have to create a shared memory area using transaction SHMA, for reading the shared memory object data, you must use method ATTACH_FOR_READ and this is possible only if the object exists and is not beeing created or changed that moment.

And for creation you have to use ATTACH_FOR_WRITE, for change ATTACH_FOR_UPDATE.

If you can make sure, that the processes will not do the same thing at the same time (parallel or multi-user processing), then shared objects will be the right choice.

Regards,

Clemens

0 Kudos

Hi Clemens.

I think you are right that shared memory objects is the right way to go.

I have created an area class in SHMA and created a Root class where I have an attribute of the type of my deep structure. I have also implemented set- and get methods for this attribute.

In my program I have entered the following code.


 data: ls_il_data           type z_action_intlay_data,
  data: r_handle           type ref to zcl_action_intlay_area.
  data: r_root               type ref to zcl_action_intlay_root.

    ... Read data and insert into ls_il_data. ...

      r_handle = zcl_action_intlay_area=>attach_for_write( ).

      create object r_root area handle r_handle.

      call method r_root->set_data
        exporting
          it_il_data = ls_il_data.

      r_handle->set_root( r_root ).
      r_handle->detach_commit( ).

When the debugger get to statement r_handle->detach_commit( ), I get exception CX_SHM_EXTERNAL_REFERENCE and additional explanation: "There are still references from the instance '$DEFAULT_INSTANCE$' in client ''

for the area 'ZCL_ACTION_INTLAY_AREA' to another area instance of the shared

objects memory or to the memory of the internal mode"

I have checked before running my program that no instances exist for area zcl_action_intlay_area in SHMM.

The exception seems to be related to the deep structure, because when I try to add a string or simple structure, I get no exception.

Do you have any idea why I have this issue with the deep structure?

Best regards

Andreas

0 Kudos

Hi Andreas,

I did not encounter this kind of error yet because I select the data in the setter from database.

My asssumption is that when you fill ls_il_data you have data that ist still referenced, i.e. assigned to a field symbol or referenced by a type ref to data field.

Obviously the detach_commit method tries to make sure there is no external reference to any data kept in the shared memory - Otherwise shared memory data could be changed uncontrolled.

If you use ASSIGN, then also use UNASSIGN before passing data to the shared memory root class attributes.

Hope this will help.

Regards,

Clemens

P.S.: Arrgh! Even more obvious: Pass the parameter 'by value' - Now you use by reference.

Edited by: Clemens Li on Mar 15, 2011 11:15 AM

0 Kudos

Hi,

I have checked the code and I have made unassign in one place where it could possibly affect this behaviour.

I have also changed the method SET_DATA so that it pass the import parameter as value. The problem still remains though.

When I look at the deep structure I want to move to shared memory I see that it for one field (DATA) have the

"Indicator for Reference Type" set, like this:



Z_ACTION_INTLAY_DATA

Component		RType	Component Type
HEADER_GUID			CRMT_OBJECT_GUID
HEADER_STRUC_NAME		TYPENAME
ITEM_STRUC_NAME			TYPENAME
DATA			X	DATA
ITEMS				Z_ACTION_INTLAY_ITEM_DATA_T

Do you think this can be the reason for the exception?

P.S I haven't written this program myself from beginning but I am now involved in upgrade to CRM 7.0 and need to handle this issue with exporting the data to shared memory in some way. This structure is used in a lot of different structures so I would prefer not to do any major changes of the structure.

Regards Andreas

0 Kudos

Hi Andreas,

Oh, yes, probably.

Not only the Shared memory area must not be referenced from outside, but also no references storeds inside are allowed to point to data objects outside. The DATA is a reference variable, TYPE REF TO DATA.

Can you see in debugger that the DATA field has a value that is not ?

If everything is , then it should be OK. If not, you have to find a way to get the values referenced and copy them to the shared memory area.

Something like this:

data:
  lr_data type ref to data.
field-symbols:
 <any>  type any,
 <any2> type any.

assign Z_ACTION_INTLAY_DATA-data->* to <any>.
create data lr_data like <any>.
assign lr_data->* to <any2>.
<any2> = <any>.
Z_ACTION_INTLAY_DATA-data = lr_data.

I did not try, but I think this way we re-created the data insode the shared memory object and have no more reference to the calling process.

Let us know if it helps. It is really important that we have a chance to gain some experience with shared objects. Documentation does not reveal too much and SAP standard use of shared objects is neither clear nor documented.

Regards,

Clemens

0 Kudos

Hi,

I have now made required changes to make this work. The proposed code by you Clemens unfortunately did not work. I had to move the data structure to a new separate internal table. Then I clear the data structure ls_il_data-data. Then it is possible to export ls_il_data and the new data structure as two separate tables and export this to memory object.

BUT: As Clemens wrote in a previous post: "If you can make sure, that the processes will not do the same thing at the same time (parallel or multi-user processing), then shared objects will be the right choice." I think in this case it is very likely that the same object will be accessed at the same time by two or more different user sessions.

So, either I have to program some locking mechanism and let the user wait for one second or so until the object can be accessed.

Or, I can use export to database. Because it seems as the problem with Export to Database was also related to refererence to DATA problem in my internal table. So if I break up this table temporarily and export them in two separate structures this approach will also work.

Best Regards Andreas

Former Member
0 Kudos

Hi ,

export LS_IL_DATA from LS_IL_DATA

to database indx(za) from wa_index

id 'Z_CONTR_CHNG'

go to se24.

Create a class with Attribute as static with Deep structure field..

Next create a Method Initialize. importing field same as attribute.

next call the Method in program and pass the deep structure,now the data is stored in gloabl.

Next where ever you wnat call the Class attribute directly into another Deep strucutre to fill.

Prabhudas