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

Часовой пояс: 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 часа


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

Сейчас этот форум просматривают: Google [Bot]


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

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