Текущее время: Чт, мар 28 2024, 20:41

Часовой пояс: UTC + 3 часа


Правила форума


ВНИМАНИЕ!

Вопросы по SAP Query и Quick View - сюда



Начать новую тему Ответить на тему  [ Сообщений: 5 ] 
Автор Сообщение
 Заголовок сообщения: Хранение внутренних таблиц в Data Cluster
СообщениеДобавлено: Вт, мар 15 2011, 10:54 
Младший специалист
Младший специалист
Аватара пользователя

Зарегистрирован:
Пн, фев 14 2011, 07:26
Сообщения: 80
Откуда: Альфа Центавра
Пол: Мужской
Привет всем. Опишу проблему.
Через Export To Database в одну таблицу помещалась несколько видов внутренних таблиц (Все были описаны в Data Dictionary). С течением времени некоторые структуры таблиц стали меняться. Соответственно обратный импорт стал невозможным. Взяв описание таблиц и структур в разработке с помощью ФМ-ов
Code:
SVRS_GET_VERSION_TABD_40
SVRS_GET_VERSION_VIED_40
SVRS_GET_VERSION_TTYD_40


И создав с помощью них include с описанием структур и их полей (на каждую предыдущую версию), большую часть данных получилось восстановить (УРА!!!). Но в одной структуре возникли проблемы. В нее был включен ракурс (.INCLUDE VIEW_NAME). Делал “перемножение", то есть сама структура менялась 3 раза, а ракурс 2 раза. Получается 2*3=6 возможных комбинаций полей. Все равно не вышло.

Вопрос №1. Можно ли получить описание полей в кластере? Ведь при не удачном импорте в дампе пишется несоответствие. То есть, к примеру, был тип NUMERIC в 3-м поле, а сейчас CHAR. В вышеупомянутой структуре, если не перехватывать исключение выходит дамп Component number 0. А в действительности component number 1 это include view.

Вопрос №2 . Хочется переделать само хранение. Есть ли стандартный класс, который хранит произвольную таблицу? Ну, какой-нибудь business storage по guid, вроде

Code:
Export_tab
Importing
  tbData Type Any Table
Returning
  Value(RESULT) Type Ref To OS_GUID.


и

Code:
Import_tab
Importing
  GUID Type GUID
Returning
  Value(RESULT) Type Ref To DATA


Из вариантов думал о:
1) Call Transformation и XML. Но размер некоторых таблиц слишком велик(500.000 – 1.000.000)
2) Может быть, стоит хранить описание таблицы (Standard, Sorted or Hashed и ключ) и описание полей (до самого домена) также в кластере? А при импорте создавать динамическую таблицу. А потом делать Import From Database?

Но хочется воспользоваться стандартным методом, если он есть.

Вариант № 1


Последний раз редактировалось matik Вт, апр 05 2011, 08:45, всего редактировалось 1 раз.

Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Хранение внутренних таблиц в Data Cluster
СообщениеДобавлено: Вт, мар 15 2011, 17:27 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Чт, авг 19 2004, 17:37
Сообщения: 1962
Откуда: Москва
Пол: Мужской
matik написал:
Но хочется воспользоваться стандартным методом, если он есть.

Есть стандартный метод - SQL, и вряд ли что умнее можно сделать. Особенно для больших таблиц.
Вон BSEG на кластере сделали, дык расстрелять бы того изобретателя... :)

_________________
"For all entries" не в SAP-ах, "for all entries" в головах! :)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Хранение внутренних таблиц в Data Cluster
СообщениеДобавлено: Вт, апр 05 2011, 08:48 
Младший специалист
Младший специалист
Аватара пользователя

Зарегистрирован:
Пн, фев 14 2011, 07:26
Сообщения: 80
Откуда: Альфа Центавра
Пол: Мужской
Решил задачу первым способом. То есть написал маленький класс ZCL_CLST_CMD для работы с кластерными таблицами, который реализует 3 простые операции: экспорта, импорта и удаления.

Возможности:

1) Динамический задавать:
• Таблицу БД
• Компрессию данных
• RELID (1-е поле таблицы)

2) Работа с несколькими(7-ми) внутренними таблицами, объединенных логически в одну ключевую запись таблицы БД. Причем таблицы могут быть объявлены локально, в самой программе.

3) Поддержка:
• Составных ключевых полей. К примеру, временной признак одно из ключевых полей таблицы БД.
• Не ключевых полей. Пример таблица WWWDATA. Хотя такая таблица явно не нормализована.
• Без мандантных кластеров.

Совместимость и эффективность на уровне statement-ов: Export To Database, Import From Database. Так как генерируются эквивалентные Native SQL команды.
Хранение чуть медленней в связи с обязательным копированием по move-corresponding в другую внутреннюю таблицу перед самим экспортом, а загрузка, может быть ничем не хуже.

4) И, конечно же, самое главное это возможность указать дополнительный ключ в кластере, где можно будет хранить описание полей структуры и описание самой внутренней таблицы. То есть смысл заключается в том, что вместе с данными запомнить техническое описание полей, тип таблицы (Standard, Sorted, Hashed), ключевые поля, Initial Size итд. Что позволит получить данные обратно, невзирая на изменения, сделанные в описаниях внутренних таблиц.


Недостатки:

1) Название и типы полей в кластере должны быть такими
CLUSTR Type INDX_CLSTR,
CLUSTD Type INDX_CLUST

Export To Internal Table – требует статического указания таблицы. Field-Symbols не подходит.

2) Хранение только FLAT Structure.

Вернее “непонятные” поля вроде ссылок и таблиц не обрабатываются. В кластере запоминаются лишь поля с элементарными типами. Много трудностей возникает с полями в виде таблиц. Думаю реализовать работу с NESTED Structure можно в новых системах, с отказом от CL_ALV_TABLE_CREATE=>CREATE_DYNAMIC_TABLE.

3) Количество различных структур создаваемых за одно выполнение программы не более 35. Хочу подчеркнуть, именно структур, а не таблиц. На одной структуре можно создать несколько видов таблиц (sorted hashed) и сколь угодно много экземпляров таблиц.
То есть в расчет количества идет только
COMPONENTS Type ABAP_COMPDESCR_TAB.

Ограничение связано методом CREATE_DYNAMIC_TABLE, так как он вызывает generate subroutine pool. Решение может быть таким – вызывать методы ZCL_CLST_CMD в отдельной программе через submit.


Благодарности: Ержану и Ване.


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Хранение внутренних таблиц в Data Cluster
СообщениеДобавлено: Вт, апр 05 2011, 08:50 
Младший специалист
Младший специалист
Аватара пользователя

Зарегистрирован:
Пн, фев 14 2011, 07:26
Сообщения: 80
Откуда: Альфа Центавра
Пол: Мужской
пример
Code:
REPORT  Z_CLST_CMD_TEST.

************************************************************************
*Постановка задачи:
* Реализовать заполнение специального буфера для отображения отчетов
* с возможностью drilldown-а в подтаблицы.
* Корректное отображение исторических данных по предыдущим периодам.
************************************************************************

Type-Pools:
ABAP.

Start-Of-Selection.
Data:
*  Класс для работы
  oAgent   Type Ref To ZCL_CLST_CMD,

*  Что кидаем в кластер
  tbData   Type Standard Table Of T001W,
  tbField  Type LVC_T_FCAT,

*  Имя кластерной таблицы лишь тут
  waKey    Type [b]WWWDATA[/b],
  waFldKey Like waKey,

*  Для импорта
  pData    Type Ref To DATA,
  pField   Type Ref To DATA,
  waLayout Type LVC_S_LAYO.
Field-Symbols:
  <tbData> Type Standard Table.

* Агент экспорта/импорта
oAgent = ZCL_CLST_CMD=>Agent.

*  Ключевые поля кластера
waKey-relid = 'OK'. " Включая RELID
waKey-OBJID = 'Z_KEY'.

* Не ключевые поля
waKey-TDATE = sy-datum.
waKey-TTIME = sy-uzeit.

*  Ключ для описания
waFldKey = waKey.
waFldKey-OBJID = 'Z_KEY_F'.

* Выбираем днные
Select * Appending Table tbData
From T001W.

* Настройка каталога полей
Call Function 'LVC_FIELDCATALOG_MERGE'
  Exporting
   i_structure_name   = 'T001W'
  Changing
   ct_fieldcat        = tbField.
*****


*  Экспорт
oAgent->export_Tables(
  waKey      = waKey
  waFldKey   = [b]waFldKey[/b]
  tbData_01  = tbData
  tbData_02  = tbField
  bCompress  = ABAP_TRUE " Сжать данные
  ).

* Очистка
clear:
  tbData,
  tbField.
*  Импорт происходит нормально если FLAT structure без include-ов
* Import %tab01 = tbData
*  From Database ZFILESTORE(00) ID 'OK'.


************************************************************************
*  Много лет спустя импорт :)
*  Когда в таблицу T001W добавили несколько полей
************************************************************************

** Не надо ссылаться на "новую" структуру
* Get Reference Of tbData Into pData.

* Если задать то будет MOVE-CORRESPONDING
* Удобно если NESTED TABLE
Get Reference Of tbField Into pField.

oAgent->import_Tables(
  Exporting
   waKey     = waKey
   waFldKey  = waFldKey
  Changing
   tbData_01 = pData
   tbData_02 = pField ).

Break-Point.
*  @see
*  pData
*  pField
*  tbData
*  tbField
Assign pData->* To <tbData>.

*  Показ сетки
waLayout-CWIDTH_OPT = ABAP_TRUE.
Call function 'REUSE_ALV_GRID_DISPLAY_LVC'
  Exporting
   IS_LAYOUT_LVC      = waLayout
   I_GRID_TITLE       = 'Список со "старыми" полями'
   it_fieldcat_lvc    = tbField
   I_SAVE             = 'U'
  Tables
   t_outtab           = <tbData>
  Exceptions
   PROGRAM_ERROR      = 1.

** Если надо удалим
* oAgent->DELETE_TABLES(
*  waKey    = waKey
*  waFldKey = waFldKey ).


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Хранение внутренних таблиц в Data Cluster
СообщениеДобавлено: Вт, апр 05 2011, 08:51 
Младший специалист
Младший специалист
Аватара пользователя

Зарегистрирован:
Пн, фев 14 2011, 07:26
Сообщения: 80
Откуда: Альфа Центавра
Пол: Мужской
сам класс
Code:
*---------------------
class ZCL_CLST_CMD definition
  public
  create private .

public section.
  type-pools ABAP .

  class-data AGENT type ref to ZCL_CLST_CMD read-only .

  class-methods class_constructor.
  methods export_tables
    importing
      !WAKEY type ANY
      !WAFLDKEY type ANY optional
      !TBDATA_01 type ANY TABLE optional
      !TBDATA_02 type ANY TABLE optional
      !TBDATA_03 type ANY TABLE optional
      !TBDATA_04 type ANY TABLE optional
      !TBDATA_05 type ANY TABLE optional
      !TBDATA_06 type ANY TABLE optional
      !TBDATA_07 type ANY TABLE optional
      !BCOMPRESS type ABAP_BOOL optional
    exceptions
      IS_NOT_STUCTURE
      IS_NOT_DICTIONARY .
  methods import_tables
    importing
      !WAKEY type ANY
      !WAFLDKEY type ANY optional
    changing
      !TBDATA_01 type ref to DATA optional
      !TBDATA_02 type ref to DATA optional
      !TBDATA_03 type ref to DATA optional
      !TBDATA_04 type ref to DATA optional
      !TBDATA_05 type ref to DATA optional
      !TBDATA_06 type ref to DATA optional
      !TBDATA_07 type ref to DATA optional
    exceptions
      IMPORT_MISMATCH_ERROR
      IS_NOT_STUCTURE
      IS_NOT_DICTIONARY
      NO_DATA .
  methods delete_tables
    importing
      !WAKEY type ANY
      !WAFLDKEY type ANY optional
    exceptions
      IS_NOT_STUCTURE
      IS_NOT_DICTIONARY .
*---------------------
protected section.

  types:
    Begin Of BUF_STRUC,
     CLUSTR  Type INDX_CLSTR,
     CLUSTD  Type INDX_CLUST,
    End Of BUF_STRUC .
  types:
    BUF_STRUC_TAB Type Standard Table Of BUF_STRUC .
  types:
    Begin Of TAB_DESC,
*     Номер талицы
     iTableInd       Type i,
*     Описание таблицы
     KEY             Type ABAP_KEYDESCR_TAB,
     INITIAL_SIZE    Type i,
     KEY_DEFKIND     Type ABAP_KEYDEFKIND,    " Надо ?
     HAS_UNIQUE_KEY  Type ABAP_BOOL,
     TABLE_KIND      Type ABAP_TABLEKIND,
* Описание полей
     STRUCT_KIND     Type ABAP_STRUCTKIND,    " Надо ?
     COMPONENTS      Type ABAP_COMPDESCR_TAB,
    End Of TAB_DESC .
  types:
TAB_DESC_STAB Type Sorted Table Of TAB_DESC With Unique Key iTableInd .
  types:
    Begin Of COMP_CASHE,
     tbCOMP  Type ABAP_COMPDESCR_TAB,
     HANDLE  Type Ref To CL_ABAP_STRUCTDESCR,
    End Of COMP_CASHE .
  types:
    COMP_CASHE_TAB Type Standard Table Of COMP_CASHE .

  data TBCASHE type COMP_CASHE_TAB .

  methods analyze_key
    importing
      !WAKEY type ANY
    exporting
      !BHAVEMANDT type ABAP_BOOL
      !SDBNAME type STRING
      !SKEYORDER type STRING
      !SNUMFLD type STRING
      !SWHERE type STRING
    exceptions
      IS_NOT_STUCTURE
      IS_NOT_DICTIONARY .
  methods create_by_handle
  final
    importing
      !OSTRUCDESC type ref to CL_ABAP_STRUCTDESCR
      !WADESC type ref to TAB_DESC
    exporting
      !PREF type ref to DATA .
  methods create_table
    importing
      !WADESC type ref to TAB_DESC
    exporting
      !PREF type ref to DATA .
  methods export_by_key
    importing
      !TBBUF type BUF_STRUC_TAB
      !WAKEY type ANY
    exceptions
      IS_NOT_STUCTURE
      IS_NOT_DICTIONARY .
  methods import_by_key
    importing
      !WAKEY type ANY
    exporting
      !TBBUF type BUF_STRUC_TAB
    exceptions
      IS_NOT_STUCTURE
      IS_NOT_DICTIONARY
      NO_DATA .
  methods move_table
    importing
      !PREF type ref to DATA
      !TBSRC type ANY TABLE .
*---------------------
private section.
endClass.
*****************************************
class ZCL_CLST_CMD implementation.
*****************************************
* Анализ ключа кластера
*****************************************
method analyze_key.
Data:
  oStrucDesc Type Ref To CL_ABAP_STRUCTDESCR,
  tbDDIC     Type DDFIELDS,
  waDDIC     Type Ref To DFIES,
  iTabix     Type SYTABIX,

  sVal       Type String,
  sOper      Type String,
  sWherePart Type String.
Field-Symbols:
  <fAny>     Type ANY.

* Описание ключа экспорта
try.
  oStrucDesc ?= CL_ABAP_STRUCTDESCR=>DESCRIBE_BY_DATA( waKey ).
catch CX_SY_MOVE_CAST_ERROR.
  Raise IS_NOT_STUCTURE.
endTry.

if oStrucDesc->IS_DDIC_TYPE( ) <> ABAP_TRUE.
  Raise IS_NOT_DICTIONARY.
endif.

* Название таблицы
sDBName = oStrucDesc->GET_RELATIVE_NAME( ).
* Описание таблицы экспорта/импорта
tbDDIC = oStrucDesc->GET_DDIC_FIELD_LIST( ).

* Цикл № 1
*****************************************
* Узнаем:
* Есть ли мандант bHaveMandt
* Последнее ключевое поле sNumFld
* Порядок ключевых полей sKeyOrder
clear bHaveMandt.
loop At tbDDIC Reference Into waDDIC Where KEYFLAG = ABAP_TRUE.
  if sy-tabix = 1 And waDDIC->DATATYPE = 'CLNT'.
   bHaveMandt = ABAP_TRUE.
  endIf.

  if sy-tabix = 1.
   sKeyOrder = waDDIC->FIELDNAME.
  else.
   Concatenate sKeyOrder ` ` waDDIC->FIELDNAME Into sKeyOrder.
  endIf.
endLoop.
sNumFld = waDDIC->FIELDNAME.

* Цикл № 2
*****************************************
* Условие для удаления и выборки sWhere
loop At tbDDIC Reference Into waDDIC Where KEYFLAG = ABAP_TRUE.
  iTabix = sy-tabix.

  if waDDIC->FIELDNAME = sNumFld.
   sOper = ` >= `.
   Assign 0 To <fAny>.
  else.
   sOper = ` = `.

*   Замарочка с мандатом
   if iTabix = 1 And bHaveMandt = ABAP_TRUE.
    Assign sy-mandt To <fAny>.
   else.
    Assign Component waDDIC->FIELDNAME Of Structure waKey To <fAny>.
   endIf.
  endIf.

  case waDDIC->INTTYPE.
   when CL_ABAP_TYPEDESCR=>TYPEKIND_NUM  Or
        CL_ABAP_TYPEDESCR=>TYPEKIND_DATE Or
        CL_ABAP_TYPEDESCR=>TYPEKIND_TIME Or
        CL_ABAP_TYPEDESCR=>TYPEKIND_CHAR Or
        CL_ABAP_TYPEDESCR=>TYPEKIND_STRING.
    Concatenate `'` <fAny> `'` Into sVal.
   when Others.
    sVal = <fAny>.
  endCase.

  Concatenate waDDIC->FIELDNAME sOper sVal Into sWherePart.
  if iTabix = 1.
   sWhere = sWherePart.
  else.
   Concatenate sWhere ` And ` sWherePart Into sWhere.
  endif.
endLoop.
endmethod.
*****************************************
* CLASS_CONSTRUCTOR
*****************************************
method class_constructor.
Create Object AGENT.
endmethod.
*****************************************
* Создание на внутренней таблицы по HANDLE (Final)
*****************************************
method create_by_handle.
Data:
  waStruc   Type Ref To DATA.
Field-Symbols:
  <waStruc> Type ANY.

Create Data waStruc Type Handle oStrucDesc.
Assign waStruc->* To <waStruc>.

* Тип
case waDesc->TABLE_KIND.
  when CL_ABAP_TABLEDESCR=>TABLEKIND_STD.
   Create Data pRef Like Standard Table Of <waStruc>
    With Non-Unique Key (waDesc->KEY) Initial Size waDesc->INITIAL_SIZE.

  when CL_ABAP_TABLEDESCR=>TABLEKIND_SORTED.
   if waDesc->HAS_UNIQUE_KEY = ABAP_TRUE.
    Create Data pRef Like Sorted Table Of <waStruc>
     With Unique Key (waDesc->KEY) Initial Size waDesc->INITIAL_SIZE.
   else.
    Create Data pRef Like Sorted Table Of <waStruc>
     With Non-Unique Key (waDesc->KEY)  Initial Size waDesc->INITIAL_SIZE.
   endIf.

  when CL_ABAP_TABLEDESCR=>TABLEKIND_HASHED.
   Create Data pRef Like Hashed Table Of <waStruc>
    With Unique Key (waDesc->KEY) Initial Size waDesc->INITIAL_SIZE.

  when Others.
* TODO Raise
endCase.
endmethod.
*****************************************
* Создание на внутренней таблицы
*****************************************
method create_table.
Data:
  waCashe    Type Ref To COMP_CASHE,
  waFldDesc  Type Ref To ABAP_COMPDESCR,
  tbFldCat   Type LVC_T_FCAT,
  waFldCat   Type Ref To LVC_S_FCAT,
  tbRef      Type Ref To DATA,
  oStrucDesc Type Ref To CL_ABAP_STRUCTDESCR,
  oTableDesc Type Ref To CL_ABAP_TABLEDESCR.
Field-Symbols:
  <tbStd>    Type Standard Table.

*  Поиск в кэше
loop At tbCashe Reference Into waCashe.
*  Если есть используем его
  if waCashe->tbCOMP = waDesc->COMPONENTS.
   oStrucDesc = waCashe->HANDLE.
   exit.
  endIf.
endLoop.

*  Если не нашли
if oStrucDesc Is Initial.
  loop At waDesc->COMPONENTS Reference Into waFldDesc.
   Append Initial Line To tbFldCat Reference Into waFldCat.

   waFldCat->fieldname = waFldDesc->name.
   waFldCat->datatype = waFldDesc->type_kind.
   waFldCat->inttype = waFldDesc->type_kind.
   waFldCat->intlen = waFldDesc->length.
   waFldCat->decimals = waFldDesc->decimals.
  endLoop.

*  Стандартная таблица
  CL_ALV_TABLE_CREATE=>CREATE_DYNAMIC_TABLE(
   Exporting
    it_fieldcatalog = tbFldCat
    I_LENGTH_IN_BYTE = ABAP_TRUE
   Importing
    ep_table        = tbRef ).
  Assign tbRef->* To <tbStd>.

  oTableDesc ?= CL_ABAP_TABLEDESCR=>DESCRIBE_BY_DATA( <tbStd> ).
  oStrucDesc ?= oTableDesc->GET_TABLE_LINE_TYPE( ).

*  Добавление
  Insert Initial Line Into Table tbCashe Reference Into waCashe.
  waCashe->HANDLE = oStrucDesc.
  waCashe->tbCOMP = waDesc->COMPONENTS.
endIf.

*  Создаем на основе HANDLE
CREATE_BY_HANDLE(
  Exporting
   waDesc     = waDesc
   oStrucDesc = oStrucDesc
  Importing
   pRef       = pRef ).
endmethod.
*****************************************
* Удаление по ключу
*****************************************
method delete_tables.
Data:
  sDBName Type String,
  sWhere  Type String.
*****************************************
DEFINE DELETE_ITEM.
*  Проанализируем ключ
  ANALYZE_KEY(
   Exporting
    waKey   = &1
   Importing
    sDBName    = sDBName
    sWhere     = sWhere
   Exceptions
    IS_NOT_STUCTURE   = 1
    IS_NOT_DICTIONARY = 2 ).
  case sy-subrc.
   when 1.
    Raise IS_NOT_STUCTURE.
   when 2.
    Raise IS_NOT_DICTIONARY.
  endCase.

*  Удаление из кластере
  Delete From (sDBName) Where (sWhere).
END-OF-DEFINITION.
*****************************************

* Просто удаляем
DELETE_ITEM waKey.

if waFldKey Is Supplied.
  DELETE_ITEM waFldKey.
endIF.
endmethod.
*****************************************
* Экспорт по ключу кластера
*****************************************
method export_by_key.
Data:
  sWhere     Type String,
  sDBName    Type String,
  bHaveMandt Type ABAP_BOOL,
  sNumFld    Type String,

  pRef       Type Ref To DATA,
  iTabix     Type INDX_SRTF2.
Field-Symbols:
  <waBuf>    Type BUF_STRUC,
  <tbExport> Type Standard Table,
  <waExport> Type ANY,
  <iTabix>   Type INDX_SRTF2,
  <fMANDT>   Type SYMANDT.

* Проанализируем ключ
ANALYZE_KEY(
  Exporting
   waKey   = waKey
  Importing
   sDBName    = sDBName
   sNumFld    = sNumFld
   sWhere     = sWhere
   bHaveMandt = bHaveMandt
  Exceptions
   IS_NOT_STUCTURE   = 1
   IS_NOT_DICTIONARY = 2 ).
case sy-subrc.
  when 1.
   Raise IS_NOT_STUCTURE.
  when 2.
   Raise IS_NOT_DICTIONARY.
endCase.
*****************************************
* Создадим таблицу
Create Data pRef Like Standard Table Of waKey.
Assign pRef->* To <tbExport>.

* Из буфера в таблицу экспорта
loop At tbBuf Assigning <waBuf>.
*  Добавим пустую строку
  iTabix = sy-tabix - 1.
  Insert Initial Line Into Table <tbExport> Assigning <waExport>.

*  Копирование из ключа и из буфера
  Move-Corresponding waKey   To <waExport>.
  Move-Corresponding <waBuf> To <waExport>.

*  Нумерация
  Assign Component sNumFld Of Structure <waExport> To <iTabix>.
  <iTabix> = iTabix.

*  Мандант ?
  Check bHaveMandt = ABAP_TRUE.
*  Не обрабатываемое исключение
  Assign Component 1 Of Structure <waExport> To <fMANDT>.
  <fMANDT> = sy-mandt.
endLoop.
*****************************************

* Удаление и вставка
Delete From (sDBName) Where (sWhere).
Insert (sDBName) From Table <tbExport>.
endmethod.
*****************************************
* Экспорт таблиц
*****************************************
method export_tables.
Data:
  tbBuf      Type BUF_STRUC_TAB,
  oStrucDesc Type Ref To CL_ABAP_STRUCTDESCR,
  oTableDesc Type Ref To CL_ABAP_TABLEDESCR,
  tbDesc     Type TAB_DESC_STAB,
  waDesc     Type TAB_DESC,
  waRDesc    Type Ref To TAB_DESC,
  pRef       Type Ref To DATA.

Field-Symbols:
  <tbData_01> Type Any Table,
  <tbData_02> Type Any Table,
  <tbData_03> Type Any Table,
  <tbData_04> Type Any Table,
  <tbData_05> Type Any Table,
  <tbData_06> Type Any Table,
  <tbData_07> Type Any Table.
*****************************************
* Если надо экспортировать описание таблиц
if waFldKey Is Supplied.

  DEFINE ADD_DESC.
  if tbData_&1 Is Supplied.
*   Номер таблицы
   waDesc-iTableInd       = &1.

*   Получение описания
   oTableDesc ?= CL_ABAP_TABLEDESCR=>DESCRIBE_BY_DATA( tbData_&1 ).
   try.
    oStrucDesc ?= oTableDesc->GET_TABLE_LINE_TYPE( ).
   catch CX_SY_MOVE_CAST_ERROR.
    Raise IS_NOT_STUCTURE.
   endTry.

   waDesc-STRUCT_KIND     = oStrucDesc->STRUCT_KIND.
   waDesc-COMPONENTS      = oStrucDesc->COMPONENTS.

*   Удаляем не обрабатываемые поля
   Delete waDesc-COMPONENTS Where
    TYPE_KIND = CL_ABAP_TYPEDESCR=>TYPEKIND_TABLE   Or
    TYPE_KIND = CL_ABAP_TYPEDESCR=>TYPEKIND_OREF    Or
    TYPE_KIND = CL_ABAP_TYPEDESCR=>TYPEKIND_IREF    Or
    TYPE_KIND = CL_ABAP_TYPEDESCR=>TYPEKIND_DREF    Or
    TYPE_KIND = CL_ABAP_TYPEDESCR=>TYPEKIND_STRUCT1 Or
    TYPE_KIND = CL_ABAP_TYPEDESCR=>TYPEKIND_STRUCT2.

   waDesc-KEY             = oTableDesc->KEY.
   waDesc-INITIAL_SIZE    = oTableDesc->INITIAL_SIZE.
   waDesc-KEY_DEFKIND     = oTableDesc->KEY_DEFKIND.
   waDesc-HAS_UNIQUE_KEY  = oTableDesc->HAS_UNIQUE_KEY.
   waDesc-TABLE_KIND      = oTableDesc->TABLE_KIND.

*   Добавим описание
   Insert waDesc Into Table tbDesc Reference Into waRDesc.

*   Создадим таблицу
   CREATE_TABLE(
    Exporting
     waDesc = waRDesc
    Importing
     pRef   = pRef ).

*   Перемешаем данные
   MOVE_TABLE(
    tbSrc = tbData_&1
    pRef  = pRef ).
   Assign pRef->* To <tbData_&1>.
  else.
   Assign tbData_&1 To <tbData_&1>.
  endIf.
  END-OF-DEFINITION.

*  Накопление описаний таблиц
  ADD_DESC 01.
  ADD_DESC 02.
  ADD_DESC 03.
  ADD_DESC 04.
  ADD_DESC 05.
  ADD_DESC 06.
  ADD_DESC 07.

*  Сжимаем описание
  Clear tbBuf.
  Export
   tbDesc = tbDesc
  To Internal Table tbBuf Compression ON.

*  Экспорт описаний
  EXPORT_BY_KEY(
   Exporting
    waKey = waFldKey
    tbBuf = tbBuf
   Exceptions
    IS_NOT_STUCTURE   = 1
    IS_NOT_DICTIONARY = 2 ).
  case sy-subrc.
   when 1.
    Raise IS_NOT_STUCTURE.
   when 2.
    Raise IS_NOT_DICTIONARY.
  endCase.

else.
  Assign tbData_01 To <tbData_01>.
  Assign tbData_02 To <tbData_02>.
  Assign tbData_03 To <tbData_03>.
  Assign tbData_04 To <tbData_04>.
  Assign tbData_05 To <tbData_05>.
  Assign tbData_06 To <tbData_06>.
  Assign tbData_07 To <tbData_07>.
endIf.

*****************************************
DEFINE DO_EXPORT.
  Export
   %tab01 = <&1_01>
   %tab02 = <&1_02>
   %tab03 = <&1_03>
   %tab04 = <&1_04>
   %tab05 = <&1_05>
   %tab06 = <&1_06>
   %tab07 = <&1_07>
  To Internal Table tbBuf Compression &2.
END-OF-DEFINITION.

* Объединим в одну таблицу
if bCompress = ABAP_TRUE.
  DO_EXPORT tbData ON.
else.
  DO_EXPORT tbData OFF.
endIf.

* Экспорт данных
EXPORT_BY_KEY(
  Exporting
   waKey = waKey
   tbBuf = tbBuf
  Exceptions
   IS_NOT_STUCTURE   = 1
   IS_NOT_DICTIONARY = 2 ).
case sy-subrc.
  when 1.
   Raise IS_NOT_STUCTURE.
  when 2.
   Raise IS_NOT_DICTIONARY.
endCase.
endmethod.
*****************************************
* Импорт по ключу кластера
*****************************************
method import_by_key.
Data:
  sDBName   Type String,
  sWhere    Type String,
  sKeyOrder Type String.
Clear tbBuf.

* Проанализируем ключ
ANALYZE_KEY(
  Exporting
   waKey   = waKey
  Importing
   sDBName    = sDBName
   sWhere     = sWhere
   sKeyOrder  = sKeyOrder
  Exceptions
   IS_NOT_STUCTURE   = 1
   IS_NOT_DICTIONARY = 2 ).
case sy-subrc.
  when 1.
   Raise IS_NOT_STUCTURE.
  when 2.
   Raise IS_NOT_DICTIONARY.
endCase.

* Просто считаем из таблицы
Select * Into Corresponding Fields Of Table tbBuf
From (sDBName)
Where (sWhere)
Order By (sKeyOrder).

if sy-dbcnt = 0.
  Raise NO_DATA.
endIf.
endmethod.
*****************************************
* Импорт таблиц
*****************************************
method import_tables.
Data:
*  Временная
  tbTmp       Type Standard Table Of SYMANDT,
  tbBuf       Type BUF_STRUC_TAB,
  tbDesc      Type TAB_DESC_STAB,
  waDesc      Type Ref To TAB_DESC,
  nInd        Type NUM2,
  sRefName    Type String,
  pRef        Type Ref To DATA,

  pPrev_01    Type Ref To DATA,
  pPrev_02    Type Ref To DATA,
  pPrev_03    Type Ref To DATA,
  pPrev_04    Type Ref To DATA,
  pPrev_05    Type Ref To DATA,
  pPrev_06    Type Ref To DATA,
  pPrev_07    Type Ref To DATA.
Field-Symbols:
  <pPrev>     Type Ref To DATA,
  <pData>     Type Ref To DATA,
  <tbData_01> Type Any Table,
  <tbData_02> Type Any Table,
  <tbData_03> Type Any Table,
  <tbData_04> Type Any Table,
  <tbData_05> Type Any Table,
  <tbData_06> Type Any Table,
  <tbData_07> Type Any Table.

* Если есть описание меняем ссылки
if waFldKey Is Supplied.
*  Импорт описания
  IMPORT_BY_KEY(
   Exporting
    waKey = waFldKey
   Importing
    tbBuf = tbBuf
   Exceptions
    IS_NOT_STUCTURE   = 1
    IS_NOT_DICTIONARY = 2
    NO_DATA           = 3 ).
  case sy-subrc.
   when 1.
    Raise IS_NOT_STUCTURE.
   when 2.
    Raise IS_NOT_DICTIONARY.
   when 3.
    Raise NO_DATA.
  endCase.

*  Описание из буфера
  Import
   tbDesc = tbDesc
  From Internal Table tbBuf.

*  Пробегаемся по записям и изменяем ссылки
  loop At tbDesc Reference Into waDesc.
   nInd = waDesc->iTableInd.
*   Создаем таблицу
   CREATE_TABLE(
    Exporting
     waDesc = waDesc
    Importing
     pRef   = pRef ).

*   Запомним предыдущую ссылку
   Concatenate `pPrev_` nInd Into sRefName.
   Assign (sRefName) To <pPrev>.

   Concatenate `tbData_` nInd Into sRefName.
   Assign (sRefName) To <pData>.

   <pPrev> = <pData>.
   <pData> = pRef.
  endLoop.
endIf.

*****************************************
* Теперь делаем обычный импорт
IMPORT_BY_KEY(
  Exporting
   waKey = waKey
  Importing
   tbBuf = tbBuf
  Exceptions
   IS_NOT_STUCTURE   = 1
   IS_NOT_DICTIONARY = 2
   NO_DATA           = 3 ).
case sy-subrc.
  when 1.
   Raise IS_NOT_STUCTURE.
  when 2.
   Raise IS_NOT_DICTIONARY.
  when 3.
   Raise NO_DATA.
endCase.

*****************************************
DEFINE SET_REF.
  if tbData_&1 Is Supplied.
   Assign tbData_&1->* To <tbData_&1>.
  else.
   Assign tbTmp To <tbData_&1>.
  endIf.
END-OF-DEFINITION.

* Установим ссылки
SET_REF 01.
SET_REF 02.
SET_REF 03.
SET_REF 04.
SET_REF 05.
SET_REF 06.
SET_REF 07.

try.
  Import
   %tab01 = <tbData_01>
   %tab02 = <tbData_02>
   %tab03 = <tbData_03>
   %tab04 = <tbData_04>
   %tab05 = <tbData_05>
   %tab06 = <tbData_06>
   %tab07 = <tbData_07>
  From Internal Table tbBuf.
catch CX_SY_IMPORT_MISMATCH_ERROR.
  Raise IMPORT_MISMATCH_ERROR.
endTry.

*****************************************
* Если передавали ссылку делаем MOVE-CORRESPONDING
DEFINE CHECH_PREV.
  if Not pPrev_&1 Is Initial.
   MOVE_TABLE(
    tbSrc = <tbData_&1>
    pRef  = pPrev_&1 ).
   tbData_&1 = pPrev_&1.
  endIf.
END-OF-DEFINITION.

CHECH_PREV 01.
CHECH_PREV 02.
CHECH_PREV 03.
CHECH_PREV 04.
CHECH_PREV 05.
CHECH_PREV 06.
CHECH_PREV 07.
endmethod.
*****************************************
* Перемещение из источника в приемник
*****************************************
method move_table.
Data:
  pDest Type Ref To DATA.
Field-Symbols:
  <tbDest> Type Any Table,
  <waSrc>  Type ANY,
  <waDest> Type ANY.

Assign pRef->* To <tbDest>.
Create Data pDest Like Line Of <tbDest>.
Assign pDest->* To <waDest>.

loop At tbSrc Assigning <waSrc>.
  Move-Corresponding <waSrc> To <waDest>.
  Insert <waDest> Into Table <tbDest>.
endLoop.
endmethod.
*****************************************
endClass.



Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 5 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB