сам класс
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.