Создание BW экстрактора на основе фунционального модуля.

Все просто, три шага:
1) Создать ФМ
2) Создать источник данных
3) Протестировать источник данных

Шаг 1. Создаем ФМ. Здесь все как обычно. Немного о его интерфейсах:

  1. *"----------------------------------------------------------------------
  2. *"*"Локальный интерфейс:
  3. *" IMPORTING
  4. *" REFERENCE(I_REQUNR) TYPE SRSC_S_IF_SIMPLE-REQUNR
  5. *" REFERENCE(I_DSOURCE) TYPE SRSC_S_IF_SIMPLE-DSOURCE OPTIONAL
  6. *" REFERENCE(I_MAXSIZE) TYPE SRSC_S_IF_SIMPLE-MAXSIZE OPTIONAL
  7. *" REFERENCE(I_INITFLAG) TYPE SRSC_S_IF_SIMPLE-INITFLAG OPTIONAL
  8. *" REFERENCE(I_READ_ONLY) TYPE SRSC_S_IF_SIMPLE-READONLY OPTIONAL
  9. *" REFERENCE(I_REMOTE_CALL) TYPE SBIWA_FLAG DEFAULT
  10. *" SBIWA_C_FLAG_OFF
  11. *" TABLES
  12. *" I_T_SELECT TYPE SRSC_S_IF_SIMPLE-T_SELECT OPTIONAL
  13. *" I_T_FIELDS TYPE SRSC_S_IF_SIMPLE-T_FIELDS OPTIONAL
  14. *" E_T_DATA STRUCTURE ZFC_LOADSTRU OPTIONAL
  15. *" EXCEPTIONS
  16. *" NO_MORE_DATA
  17. *" ERROR_PASSED_TO_MESS_HANDLER
  18. *"----------------------------------------------------------------------

параметры буфера обмена при экстракции
I_REQUNR — тестовый запуск, или запус экстракции. Система сама заполняет этот параметр. Параметр обязателен.
I_DSOURCE — Название источника данных, созданного в RSO2. При тесте через RSA3 или запуске экстракции заполняется системой. Параметр опционален.
I_MAXSIZE — максимальный размер передаваемого пакета данных. Устанавливается системой, по умолчанию = 100. Можно увеличить. Параметр опционален.
Остальные параметры
I_INITFLAG — Параметр опционален. = X по умолчанию. Заполняется системой.
I_REMOTE_CALL — Параметр обязателен. Обозначает вариант удаленного запуска (RFC)
I_READ_ONLY — Параметр опционален. Без комментариев =)

Таблицы:

На вход:
I_T_SELECT — Передаем (или уже в самом ФМ формируем) поля для условий (Where), эти поля для условий потом будут отражены в источнике данных создаваемом в RSO2.
I_T_FIELDS — Список полей для экстракции. Эти поля потом будут отражены в источнике данных создаваемом в RSO2, как поля для экстракции.

На выход:
E_T_DATA — таблица со структурой данных, подаваемых на выход. Типизация LIKE — структура. Сама структура должна быть строго типизированной (Не допускается типизация вида — «Тип ссылка на». Допускается только типизация «TYPE»).

Особые ситуации:

NO_MORE_DATA — обязательная особая ситуация, используется когда ведется работа с курсорами БД. Вызывается когда кончаются данные для выборки.

Полный исходный код ФМ:

  1. FUNCTION Z_FI_EKPOUT.
  2. *"----------------------------------------------------------------------
  3. *"*"Локальный интерфейс:
  4. *" IMPORTING
  5. *" REFERENCE(I_REQUNR) TYPE SRSC_S_IF_SIMPLE-REQUNR
  6. *" REFERENCE(I_DSOURCE) TYPE SRSC_S_IF_SIMPLE-DSOURCE OPTIONAL
  7. *" REFERENCE(I_MAXSIZE) TYPE SRSC_S_IF_SIMPLE-MAXSIZE OPTIONAL
  8. *" REFERENCE(I_INITFLAG) TYPE SRSC_S_IF_SIMPLE-INITFLAG OPTIONAL
  9. *" REFERENCE(I_READ_ONLY) TYPE SRSC_S_IF_SIMPLE-READONLY OPTIONAL
  10. *" REFERENCE(I_REMOTE_CALL) TYPE SBIWA_FLAG DEFAULT
  11. *" SBIWA_C_FLAG_OFF
  12. *" TABLES
  13. *" I_T_SELECT TYPE SRSC_S_IF_SIMPLE-T_SELECT OPTIONAL
  14. *" I_T_FIELDS TYPE SRSC_S_IF_SIMPLE-T_FIELDS OPTIONAL
  15. *" E_T_DATA STRUCTURE ZFC_LOADSTRU OPTIONAL
  16. *" EXCEPTIONS
  17. *" NO_MORE_DATA
  18. *" ERROR_PASSED_TO_MESS_HANDLER
  19. *"----------------------------------------------------------------------
  20.  
  21. TYPE-POOLS: SRSC, SBIWA.
  22.  
  23. DATA: RSAL_SAVE_SUBRC LIKE SY-SUBRC,
  24. RSAL_S_LOGPARMS LIKE RSLOGPARMS.
  25.  
  26. DEFINE LOG_WRITE.
  27. RSAL_SAVE_SUBRC = SY-SUBRC.
  28. RSAL_S_LOGPARMS-MSGTY = &1.
  29. RSAL_S_LOGPARMS-MSGID = &2.
  30. RSAL_S_LOGPARMS-MSGNO = &3.
  31. RSAL_S_LOGPARMS-MSGV1 = &4.
  32. RSAL_S_LOGPARMS-MSGV2 = &5.
  33. CALL FUNCTION 'RSAL_LOG_WRITE'
  34. EXPORTING
  35. I_MSGTY = RSAL_S_LOGPARMS-MSGTY
  36. I_MSGID = RSAL_S_LOGPARMS-MSGID
  37. I_MSGNO = RSAL_S_LOGPARMS-MSGNO
  38. I_MSGV1 = RSAL_S_LOGPARMS-MSGV1
  39. I_MSGV2 = RSAL_S_LOGPARMS-MSGV2.
  40. SY-SUBRC = RSAL_SAVE_SUBRC.
  41.  
  42. * data: zfc_data like zekpout occurs 0 with header line.
  43. *
  44. * select * from zekpout into corresponding fields of table zfc_data.
  45.  
  46. * Auxiliary Selection criteria structure
  47. DATA: L_S_SELECT TYPE SRSC_S_SELECT.
  48.  
  49. * Maximum number of lines for DB table
  50. STATICS: S_S_IF TYPE SRSC_S_IF_SIMPLE,
  51.  
  52. * counter
  53. S_COUNTER_DATAPAKID LIKE SY-TABIX,
  54.  
  55. * cursor
  56. S_CURSOR TYPE CURSOR.
  57. * Select ranges
  58. L_R_D_CA FOR Zekpout-D_CA,
  59. L_R_D_RU FOR Zekpout-D_RU,
  60. L_R_D_CU FOR Zekpout-D_CU,
  61. L_R_D_DP FOR Zekpout-D_DP,
  62. L_R_D_AC FOR Zekpout-D_AC,
  63. L_R_D_PA FOR Zekpout-D_PA,
  64. L_R_D_FL FOR Zekpout-D_FL,
  65. L_R_D_DC FOR Zekpout-D_DC,
  66. L_R_D_CM FOR Zekpout-D_CM,
  67. L_R_D_CR FOR Zekpout-D_CR,
  68. L_R_D_FS FOR Zekpout-D_FS,
  69. L_R_D_CT FOR Zekpout-D_CT,
  70. L_R_P_AMOUNT FOR Zekpout-P_AMOUNT,
  71. L_R_P_COMMENT FOR Zekpout-P_COMMENT
  72. .
  73.  
  74. * Initialization mode (first call by SAPI) or data transfer mode
  75. * (following calls) ?
  76. IF I_INITFLAG = SBIWA_C_FLAG_ON.
  77.  
  78. ************************************************************************
  79. * Initialization: check input parameters
  80. * buffer input parameters
  81. * prepare data selection
  82. ************************************************************************
  83.  
  84. * Check DataSource validity
  85. * CASE I_DSOURCE.
  86. * WHEN 'ZGET_FC_DATA'.
  87. * WHEN OTHERS.
  88. * IF 1 = 2. MESSAGE E009(R3). ENDIF.
  89. ** this is a typical log call. Please write every error message like this
  90. * LOG_WRITE 'E' "message type
  91. * 'R3' "message class
  92. * '009' "message number
  93. * I_DSOURCE "message variable 1
  94. * ' '. "message variable 2
  95. * RAISE ERROR_PASSED_TO_MESS_HANDLER.
  96. * ENDCASE.
  97.  
  98. APPEND LINES OF I_T_SELECT TO S_S_IF-T_SELECT.
  99.  
  100. * Fill parameter buffer for data extraction calls
  101. S_S_IF-REQUNR = I_REQUNR.
  102. S_S_IF-DSOURCE = I_DSOURCE.
  103. S_S_IF-MAXSIZE = I_MAXSIZE.
  104.  
  105. * Fill field list table for an optimized select statement
  106. * (in case that there is no 1:1 relation between InfoSource fields
  107. * and database table fields this may be far from beeing trivial)
  108. APPEND LINES OF I_T_FIELDS TO S_S_IF-T_FIELDS.
  109.  
  110. ELSE. "Initialization mode or data extraction ?
  111.  
  112. ************************************************************************
  113. * Data transfer: First Call OPEN CURSOR + FETCH
  114. * Following Calls FETCH only
  115. ************************************************************************
  116.  
  117. * First data package -> OPEN CURSOR
  118. IF S_COUNTER_DATAPAKID = 0.
  119.  
  120. * Fill range tables BW will only pass down simple selection criteria
  121. * of the type SIGN = 'I' and OPTION = 'EQ' or OPTION = 'BT'.
  122. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_CA'.
  123. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_CA.
  124. APPEND L_R_D_CA.
  125.  
  126. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_RU'.
  127. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_RU.
  128. APPEND L_R_D_RU.
  129.  
  130. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_CU'.
  131. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_CU.
  132. APPEND L_R_D_CU.
  133.  
  134. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_DP'.
  135. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_DP.
  136. APPEND L_R_D_DP.
  137.  
  138. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_AC'.
  139. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_AC.
  140. APPEND L_R_D_AC.
  141.  
  142. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_PA'.
  143. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_PA.
  144. APPEND L_R_D_PA.
  145.  
  146. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_FL'.
  147. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_FL.
  148. APPEND L_R_D_FL.
  149.  
  150. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_DC'.
  151. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_DC.
  152. APPEND L_R_D_DC.
  153.  
  154. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_CM'.
  155. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_CM.
  156. APPEND L_R_D_CM.
  157.  
  158. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_CR'.
  159. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_CR.
  160. APPEND L_R_D_CR.
  161.  
  162. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_FS'.
  163. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_FS.
  164. APPEND L_R_D_FS.
  165.  
  166. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_CT'.
  167. MOVE-CORRESPONDING L_S_SELECT TO L_R_D_CT.
  168. APPEND L_R_D_CT.
  169.  
  170. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_P_AMOUNT'.
  171. MOVE-CORRESPONDING L_S_SELECT TO L_R_P_AMOUNT.
  172. APPEND L_R_P_AMOUNT.
  173.  
  174. LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'D_P_COMMENT'.
  175. MOVE-CORRESPONDING L_S_SELECT TO L_R_P_COMMENT.
  176. APPEND L_R_P_COMMENT.
  177.  
  178. * Determine number of database records to be read per FETCH statement
  179. * from input parameter I_MAXSIZE. If there is a one to one relation
  180. * between DataSource table lines and database entries, this is trivial.
  181. * In other cases, it may be impossible and some estimated value has to
  182. * be determined.
  183. OPEN CURSOR WITH HOLD S_CURSOR FOR
  184. SELECT (S_S_IF-T_FIELDS) FROM Zekpout
  185. WHERE D_CA IN L_R_D_CA
  186. AND D_RU IN L_R_D_RU
  187. AND D_CU IN L_R_D_CU
  188. AND D_DP IN L_R_D_DP
  189. AND D_AC IN L_R_D_AC
  190. AND D_PA IN L_R_D_PA
  191. AND D_FL IN L_R_D_FL
  192. AND D_DC IN L_R_D_DC
  193. AND D_CM IN L_R_D_CM
  194. AND D_CR IN L_R_D_CR
  195. AND D_FS IN L_R_D_FS
  196. AND D_CT IN L_R_D_CT
  197. AND P_AMOUNT IN L_R_P_AMOUNT
  198. AND P_COMMENT IN L_R_P_COMMENT
  199. .
  200.  
  201. ENDIF. "First data package ?
  202.  
  203. * Fetch records into interface table.
  204. * named E_T_'Name of extract structure'.
  205. FETCH NEXT CURSOR S_CURSOR
  206. APPENDING CORRESPONDING FIELDS
  207. OF TABLE E_T_DATA
  208. PACKAGE SIZE S_S_IF-MAXSIZE.
  209.  
  210. IF SY-SUBRC <> 0.
  211. CLOSE CURSOR S_CURSOR.
  212. RAISE NO_MORE_DATA.
  213.  
  214. S_COUNTER_DATAPAKID = S_COUNTER_DATAPAKID + 1.
  215.  
  216. ENDIF. "Initialization mode or data extraction ?
  217.  

Шаг 2. В транзакции RSO2 создать источник данных
Указываем раннее созданный ФМ а так же нашу выходную структуру данных.
rso2

Шаг 3. Протестировать экстрактор можно через транзакцию RSA3.

Данные для статьи. Исходный код модуля в частности, предоставлены — kenzhemax

Комментарии