SAPфорум.RU https://www.sapboard.ru/forum/ |
|
Хранение внутренних таблиц в Data Cluster https://www.sapboard.ru/forum/viewtopic.php?f=13&t=68053 |
Страница 1 из 1 |
Автор: | matik [ Вт, мар 15 2011, 10:54 ] |
Заголовок сообщения: | Хранение внутренних таблиц в Data Cluster |
Привет всем. Опишу проблему. Через 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 |
Автор: | Parazit [ Вт, мар 15 2011, 17:27 ] |
Заголовок сообщения: | Re: Хранение внутренних таблиц в Data Cluster |
matik написал: Но хочется воспользоваться стандартным методом, если он есть. Есть стандартный метод - SQL, и вряд ли что умнее можно сделать. Особенно для больших таблиц. Вон BSEG на кластере сделали, дык расстрелять бы того изобретателя... |
Автор: | matik [ Вт, апр 05 2011, 08:48 ] |
Заголовок сообщения: | Re: Хранение внутренних таблиц в Data Cluster |
Решил задачу первым способом. То есть написал маленький класс 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. Благодарности: Ержану и Ване. |
Автор: | matik [ Вт, апр 05 2011, 08:50 ] |
Заголовок сообщения: | Re: Хранение внутренних таблиц в Data Cluster |
пример 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 ). |
Автор: | matik [ Вт, апр 05 2011, 08:51 ] |
Заголовок сообщения: | Re: Хранение внутренних таблиц в Data Cluster |
сам класс 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. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |