вторник, 30 ноября 2010 г.

Тихий лог

Почитал тут How To... Automate Error Stack Analysis - идея понравилась...

Но после обсуждения, было принято решение, сделать чуть по своему... не выкидывать записи в error stack, а просто писать лог в случае если мы попали на какую-то некорректную ситуацию. Писать что то в Z-table как то не тянуло... решили использовать стандартный DTP LOG - RSBMONMESS

Вот ещё немного табличек с логами.

p.s. Первый же запуск дал много информации к размышлению... и как у пользователей всё сходиться, ума не приложу.

DATA:
ls_MSG TYPE RSPC_S_MSG.

ls_MSG-MSGID = 'ZLOG'.
ls_MSG-MSGNO = '000'.
ls_MSG-MSGTY = 'I'.
ls_MSG-MSGV1 = 'Х..... >> Y..... Загрузка цены'.
ls_MSG-MSGV2 = SPACE.
ls_MSG-MSGV3 = SPACE.
ls_MSG-MSGV4 = SPACE.

CONCATENATE -P...
-C...
-O...
-D...
INTO ls_MSG-MSGV2
SEPARATED BY SPACE.

CALL METHOD LOG->ADD_MSG
EXPORTING
I_S_MSG = ls_MSG.

вторник, 23 ноября 2010 г.

Сам себе дельта

По различным причинам, иногда приходиться делать следующий финт при загрузке данные в DSO.

1.Приходят записи
а.по определенным ключам из DSO цели считываются уже существующие значения, выставляется RECORDMODE = 'D', записи помещаются в результат
b.идет обработка пришедших строк, записи помещаются в результат

В принципе, всё хорошо работает. Но тут столкнулись с ситуацией, что дельта формируемая уже из целевой DSO может вызвать большие изменения в системе, при описанном подходе... хотя по факту изменений может и не быть...

В принципе, можно было бы реализовать внутри блока 1b разного рода проверки, на наличие идентичной записи... но читабельность кода была бы хуже, да и душа требовала чего то более универсального.

Как мне кажется был придуман интересный способ, как это сделать красиво :)
Схематично выглядит ~ следующее..

0. Объявляется сортированная таблица = RESULT_PAK с ключами по всем полям кроме RECORD
1.Приходят записи
а.по определенным ключам из DSO цели считываются уже существующие значения, выставляется RECORD = -1, записи помещаются в результат
b.идет обработка пришедших строк, RECORD = 1, записи помещаются в результат с помощью операнда COLLECT
c. Записи с
RECORD = 0 >> отбрасываются
RECORD = 1 >> RECORDMODE = SPACE
RECORD = -1>> RECORDMODE = 'D'

Вот так и живём... :)

ABAP. Штаны через голову

Иногда надо узнать значение переменной в вызывающей программе, особенно когда работаешь с стандартными модулями... АБАР'еры подсказали метод, единственно - действует только для глобальных переменных.

Синтаксис:
FIELD-SYMBOLS TYPE ANY.
ASSIGN ('(<имя программы>)структура') TO .

Пример:

REPORT ZCALL_LEVEL2

FIELD-SYMBOLS TYPE ANY.
ASSIGN ('(ZCALL_LEVEL1)SODAT') TO .

пятница, 19 ноября 2010 г.

Авторизация +

Т.к. авторизация была по требованию бизнеса настроена динамически от логина пользователя (+ считается через exit-переменную), то следующим требованием пришел запрос - как бы посмотреть, что рассчитываются пользователю.

Был проведен анализ существующих ФМ, итого...

BAPI_USER_GET_DETAIL - информация о пользователе

SUSR_USER_AUTH_FOR_OBJ_GET << возможно получить объекты авторизации
S_RS_AUTH - по объекту, можно выйти на exit-переменные

Но это не так интересно... интересно другие

RSEC_GET_AUTH_FOR_USER - модуль собственно делает основную работу, вызывая exit'ы
RSSB_GET_AUTH_FOR_USER - тоже самое, но у учетом авторизация *

Для определения логина текущего пользователя, соответственно использовалась sy-uname.
В данном случае exit работал всё равно для текущего пользователя... анализ транзакции RSUDO

Нашел интересный метод RSEC_GET_USERNAME который используется для подмены пользователя RSUDO. Взял на вооружение.

EXPORT uname FROM 'VALERIV02MOS' TO MEMORY ID 'RSECUNAME'.

среда, 17 ноября 2010 г.

A что это у Вас тут торчит?

Правил ошибочку в exit'e переменной, и случайно заметил параметр у модуля (как то раньше не обращал на это внимание).

FUNCTION EXIT_SAPLRRS0_001.
*" CHANGING
*" VALUE(C_S_CUSTOMER) TYPE RRO04_S_CUSTOMER OPTIONAL

Не смог понять зачем данный параметр может быть использован?
Задал вопрос на sapforum, посмотрим силу всемирного разума...

p.s. Подебажил немного... действительно SAP имеет на параметр некоторые виды, правда так и не догнал какие...
Ещё эта подпись "ACN - наводит на ощущение, что был разум и была мысль, вот какая только неясно...

В модуле RRS_VAR_VALUES_EXIT_BEFORE, можно увидеть

l_s_customer-vproctp = -vproctp. " ACN
CALL CUSTOMER-FUNCTION '001'
...
-vproctp = l_s_customer-vproctp. " ACN


да, и нашел красивый способ делать всякие сравнения (там-же)
Ну да, BW'шники знают ABAP но не на столько хорошо... :) Учиться никогда не поздно, в общем.

CONSTANTS:
* processing type of a reporting variable
BEGIN OF rro04_c_vproctp,
reppath TYPE rro04_s_globv-vproctp VALUE '1',
userexit TYPE rro04_s_globv-vproctp VALUE '3',
sapexit TYPE rro04_s_globv-vproctp VALUE '4',
table TYPE rro04_s_globv-vproctp VALUE '5', "Globv Vorschlag
authority TYPE rro04_s_globv-vproctp VALUE '6',
shiftuser TYPE rro04_s_globv-vproctp VALUE '9', "Nielson
END OF rro04_c_vproctp,

BEGIN OF rro04_ca_vproctp_exit_table,
userexit TYPE rro04_s_globv-vproctp VALUE rro04_c_vproctp-userexit,
sapexit TYPE rro04_s_globv-vproctp VALUE rro04_c_vproctp-sapexit,
table TYPE rro04_s_globv-vproctp VALUE rro04_c_vproctp-table,
authority TYPE rro04_s_globv-vproctp VALUE rro04_c_vproctp-authority,
END OF rro04_ca_vproctp_exit_table,

BEGIN OF rro04_ca_vproctp_exit,
userexit TYPE rro04_s_globv-vproctp VALUE rro04_c_vproctp-userexit,
sapexit TYPE rro04_s_globv-vproctp VALUE rro04_c_vproctp-sapexit,
END OF rro04_ca_vproctp_exit,

И теперь вкусное...

LOOP AT c_thx_var ASSIGNING
WHERE vproctp CA rro04_ca_vproctp_exit_table
AND vproctp NE rro04_c_vproctp-table
AND processed EQ rs_c_false.

IF -vproctp EQ rro04_c_vproctp-authority.