При автоматических обработках иногда бывает, что документ надо бы провести, но провести его ну никак нельзя, так как период проводки или уже закрыт или еще не открыт. Причем периодов этих надо проверять как минимум три. Это FI, MM ну и CO. Первые два проверяются следующими функциями:
FI =
FI_PERIOD_CHECKMM =
MARV_SINGLE_READCO -> Пока не знаю, было не нужно, если кто знает, пишите ::)
Для ММ как известно может быть открыто максимум два периода, текущий и предыдущий. Данные находятся в таблице MARV, так что можно их прочитать и самому, а можно использовать ФМ MARV_SINGLE_READ.
DATA: s_marv LIKE marv.
CALL FUNCTION 'MARV_SINGLE_READ'
EXPORTING
kzrfb = 'X'
bukrs = l_bukrs
IMPORTING
wmarv = s_marv
EXCEPTIONS
not_found = 1
wrong_call = 2
OTHERS = 3.
Из параметров вроде как все и так ясно:
KZRFB LIKE MTCOM-KZRFB - В общем данные берутся из буфера, если флажок = space, а если нет, то читаются из БД, ну в принципе, если мы сильно оптимизируем программу, да плюс к этому читаем эти данные часто, то при первом вызове можно поставить флажок в значение "X", а все дальнейшие... ну дальнейшие проводки, можно вообще больше не читать ;), так как вряд ли попадете на смену периода, хотя кто их пользователей знает.
BUKRS LIKE T001-BUKRS - Код БЕ, к которой принадлежит ваш заводик. Можно прочитать и самому, а можно воспользоваться ФМ
SD_GET_KOKRS_BUKRS_FROM_WERKS http://sapforum.biz/index.php/topic,179.0.html (http://sapforum.biz/index.php/topic,179.0.html)
MAXTZ LIKE MTCOM-MAXTZ - Ну а этот параметр, судя по всему уже не рабочий, так как текст где он использовался теперь закомментирован, ну по крайней мере с версии 4.6 так точно.
WMARV LIKE MARV - Возвращается нам структура, из которой и можно взять данные по открытым периодам проводки. Структуру смотрим в словаре, там вроде как все прозрачно.
Теперь, что касается FI, тут все чуток сложнее, так как периоды могут быть открыты любые, это во-первых, а во-вторых, периоды могут быть открыты например только для групп счетов, так что тут чуток сложнее, хотя если даныне нужны только в общем виде, то код следующий
DATA: l_oper LIKE t001b-frpe1.
CALL FUNCTION 'FI_PERIOD_CHECK'
EXPORTING
i_bukrs = l_bukrs
i_gjahr = s_marv-lfgja
i_koart = '+'
i_konto = '+'
i_monat = l_monat
IMPORTING
e_oper = l_oper
EXCEPTIONS
error_period = 1
error_period_acc = 2
OTHERS = 3.
i_gjahr - Год, для которого хотим получить разрешенные периоды проводки.
i_koart - Вид счета, ну тут вариантов много или задем этот самый вид счета или "+", если интересует для всех счетов.
i_konto - Конктретный счет, если знаем ну или как обычно маска "+", если вообще для всех счетов.
На выходе имеем:
L_OPER = Первый разрешенный период проводки (временной интервал 1)
Что то не совсем понятно как с FI-периодами, у меня при тестировании функция что-то показывает, только если дата отличается от текущего периода на целый год.
Пример, какой то, нашел на sapnet http://sapnet.ru/viewtopic.php?t=630&highlight=fiperiodcheck
Буду разбираться.
Цитата: Паганель від Травень 23, 2011, 09:17:31 ПП
Что то не совсем понятно как с FI-периодами, у меня при тестировании функция что-то показывает, только если дата отличается от текущего периода на целый год.
У меня вызывалось так:
* Проверим текущий период проводки
l_monat = s_marv-lfmon.
CALL FUNCTION 'FI_PERIOD_CHECK'
EXPORTING
i_bukrs = l_region
i_gjahr = s_marv-lfgja
i_koart = '+'
i_konto = '+'
i_monat = l_monat
IMPORTING
e_oper = l_oper
EXCEPTIONS
error_period = 1
error_period_acc = 2
OTHERS = 3.
IF sy-subrc = 0.
CONCATENATE s_marv-lfgja s_marv-lfmon INTO lr_period-low.
APPEND lr_period.
ENDIF.
* Проверим предыдущий период проводки
l_monat = s_marv-vmmon.
CALL FUNCTION 'FI_PERIOD_CHECK'
EXPORTING
i_bukrs = l_region
i_gjahr = s_marv-vmgja
i_koart = '+'
i_konto = '+'
i_monat = l_monat
IMPORTING
e_oper = l_oper
EXCEPTIONS
error_period = 1
error_period_acc = 2
OTHERS = 3.
IF sy-subrc = 0.
CONCATENATE s_marv-vmgja s_marv-vmmon INTO lr_period-low.
APPEND lr_period.
ENDIF.
Спасибо.
Кстати, для CO_периодов, есть куча FM, правда на скорую руку, не смог разобраться, так что склепал небольшой form для проверки, сильно не пинайте, учту любую критику.
Основная идея в том, что в CO (как я понимаю) периоды открыты, а закрытие определенных операций по периоду фиксируется в табличке kaps (тр. okp1), при этом каждый месяц (период) представлен отдельной колонкой в таблице PSP001-PSP016, как что пришлось использовать динамические условия where.
Выборка думаю понятна, если необходимо то поля можно посмотреть в указанной табличке.
FORM check_co_period
USING rs_date TYPE sy-datum
CHANGING is_open.
DATA: cond(72) TYPE c,
itab LIKE TABLE OF cond,
lt_kaps LIKE kaps OCCURS 0 WITH HEADER LINE.
CONCATENATE 'KOKRS = ''1000''' '' INTO cond.
APPEND cond TO itab.
CONCATENATE 'AND GJAHR = ''' sy-datum+0(4) '''' INTO cond.
APPEND cond TO itab.
CONCATENATE 'AND VERSN = ''0''' '' INTO cond.
APPEND cond TO itab.
CONCATENATE 'AND PSP0' sy-datum+4(2)' = ''X''' INTO cond.
APPEND cond TO itab.
TRY.
SELECT *
FROM kaps INTO CORRESPONDING FIELDS OF TABLE lt_kaps
WHERE (itab).
CATCH cx_sy_dynamic_osql_error.
MESSAGE `Wrong WHERE condition!` TYPE 'I'.
ENDTRY.
IF sy-subrc NE 0. " Записи в таблице блокирования не найдены
is_open = 'X'.
ENDIF.
ENDFORM.
P.S. Спасибо Уукрулу за помощь в формировании динамического селекта, а то что то я сплоховал
Цитатау тебя там кавычки лишние это раз, два пробелы забыл ставить между равно.. это ж абап сука.. там пробелы важно ставить
Видимо лыжи не едут или... не получается каменный цветок, в смысле проверить FI периода, ниже куча разных вариантов ни один из них не работает, и где ошибка? (Вариант "в ДНК" не предлагать) :)
REPORT zmm_period.
DATA: is_open TYPE c, L_KOART LIKE T001B-MKOAR.
DATA: s_marv LIKE marv, stdat TYPE sy-datum, edat TYPE sy-datum , l_oper LIKE T001B-FRPE1.
PARAMETERS: p_date TYPE sy-datum OBLIGATORY.
START-OF-SELECTION.
PERFORM check_mm_period
USING p_date
'X'
CHANGING s_marv
is_open.
WRITE:/ 'MM is open', is_open.
*L_KOART = '+'. " Общий
*
*PERFORM check_fi_period
* USING L_KOART
* s_marv
* CHANGING
* l_oper
* is_open.
*
* WRITE:/ 'FI is open +', is_open, 'период', l_oper.
*
* L_KOART = 'M'. " Общий
*
*PERFORM check_fi_period
* USING L_KOART
* s_marv
* CHANGING
* l_oper
* is_open.
*
* WRITE:/ 'FI is open - M', is_open, 'период', l_oper.
*
* L_KOART = 'D'. " Дебиторка
*
*PERFORM check_fi_period
* USING L_KOART
* s_marv
* CHANGING
* l_oper
* is_open.
*
* WRITE:/ 'FI is open - M', is_open, 'период', l_oper.
PERFORM check_fi_period_new
USING p_date
CHANGING is_open.
WRITE:/ 'FI is open - ', is_open.
*&---------------------------------------------------------------------*
*& Form check_fi_period
*&---------------------------------------------------------------------*
FORM check_fi_period
USING I_KOART LIKE T001B-MKOAR
rs_marv LIKE marv
CHANGING
l_oper LIKE T001B-FRPE1
is_open type c.
" DATA: l_OPER LIKE T001B-FRPE1,
data: current_open type c, I_MONAT LIKE T001B-FRPE1.
CLEAR is_open.
i_monat = rs_marv-lfmon .
* Проверим текущий период проводки
CALL FUNCTION 'FI_PERIOD_CHECK'
EXPORTING
i_bukrs = '1020'
i_gjahr = rs_marv-lfgja
i_koart = '+'
i_konto = '+'
i_monat = i_monat
IMPORTING
e_oper = l_oper
EXCEPTIONS
error_period = 1
error_period_acc = 2
OTHERS = 3.
IF sy-subrc = 0.
current_open = 'X'.
ENDIF.
* Проверим предыдущий период проводки
i_monat = rs_marv-vmmon.
CALL FUNCTION 'FI_PERIOD_CHECK'
EXPORTING
i_bukrs = '1020'
i_gjahr = rs_marv-vmgja
i_koart = '+'
i_konto = '+'
i_monat = i_monat
IMPORTING
e_oper = l_oper
EXCEPTIONS
error_period = 1
error_period_acc = 2
OTHERS = 3.
IF sy-subrc = 0 and current_open = 'X'.
is_open = 'X'.
ENDIF.
ENDFORM. "check_fi_period
FORM check_fi_period_new
USING rs_date TYPE sy-datum
CHANGING is_open.
DATA: monat LIKE t001b-frpe1.
DATA: e_monat LIKE bkpf-monat.
DATA: e_gjahr LIKE bkpf-gjahr.
DATA: h_poper LIKE ckmlpp-poper. "Месяц
DATA: h_bdatj LIKE ckmlpp-bdatj. "Год
is_open = 'X'.
CALL FUNCTION 'FI_PERIOD_DETERMINE'
EXPORTING
i_bukrs = '1020'
i_budat = rs_date
IMPORTING
e_monat = e_monat
e_gjahr = e_gjahr.
h_poper = e_monat.
h_bdatj = e_gjahr.
monat = h_poper.
CALL FUNCTION 'FI_PERIOD_CHECK'
EXPORTING
i_bukrs = '1020'
i_gjahr = h_bdatj
i_koart = '+'
i_konto = '+'
i_monat = monat
EXCEPTIONS
error_period = 1
error_period_acc = 2.
IF sy-subrc NE 0.
CLEAR is_open.
ENDIF.
ENDFORM.
Цитата: Паганель від Травень 24, 2011, 03:30:48 ПП
Видимо лыжи не едут или... не получается каменный цветок, в смысле проверить FI периода, ниже куча разных вариантов ни один из них не работает, и где ошибка? (Вариант "в ДНК" не предлагать) :)
Да и чем же всё-таки закончилась проверка с периодами для FI ?
да вроде бы работает...