SAP R/3 форум ABAP консультантов
Russian ABAP Developer's Club

Home - FAQ - Search - Memberlist - Usergroups - Profile - Log in to check your private messages - Register - Log in - English
Blogs - Weblogs News

Выделить месяцы из диапазона дат



 
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ABAP
View previous topic :: View next topic  
Author Message
Tomatos
Участник
Участник


Age: 38
Joined: 20 Sep 2010
Posts: 24

PostPosted: Tue Apr 17, 2012 2:30 pm    Post subject: Выделить месяцы из диапазона дат Reply with quote

Добрый день!

Через Select-OPTIONS вводится диапазон дат, например 01.01.2012 - 14.04.2012. Как можно разбить введенный диапазон на месяца, т.е. январь (01.01.2012-31.01.2012), февраль, март, апрель (01.04.2012-14.04.2012)?
Back to top
View user's profile Send private message
Armann
Модератор
Модератор



Joined: 01 Jan 2008
Posts: 422
Location: Moscow

PostPosted: Tue Apr 17, 2012 2:57 pm    Post subject: Reply with quote

В свое время сделал так - составлям табличку дат, начиная с какого нить лохматого 2000 и заканчивая скажем +3 года к текущей дате, что нить вроде такого:

20000101
20000201
...
20120401
20120501
....
20151201

где, перед добавлением записи проверял, подходит под условия select-options. В итоге на выходе имеем табличку с датами, каждая из которых представляет собой первый день нужного нам периода.
Более красивого способа не нашел

далее исключал те даты, что не подходят под условия select-options, в итоге в табличке оставались только нужные мне периоды. Можно проверять перед добавленим
Back to top
View user's profile Send private message Blog
bimit
Специалист
Специалист



Joined: 11 Jul 2011
Posts: 56

PostPosted: Wed Apr 18, 2012 7:50 am    Post subject: Re: Выделить месяцы из диапазона дат Reply with quote

Tomatos wrote:
Добрый день!

Через Select-OPTIONS вводится диапазон дат, например 01.01.2012 - 14.04.2012. Как можно разбить введенный диапазон на месяца, т.е. январь (01.01.2012-31.01.2012), февраль, март, апрель (01.04.2012-14.04.2012)?


Можно свой код написать и добавить в свой ФМ и будет красиво Smile

Код примерно такой, есть недочеты, но лень уже было дальше расписывать Wink

Code:
SELECTION-SCREEN BEGIN OF BLOCK b_org.
SELECT-OPTIONS: so_prd FOR bkpf-budat.
SELECTION-SCREEN   END OF BLOCK b_org.

DATA:     l_begd    TYPE d,
          l_endd    TYPE d,
          mnth_begda(2),
          mnth_endda(2),
          gv_year(4),
          gv_mnth(2),
          n TYPE n.

DATA: BEGIN OF s_data,
      l_begd    TYPE d,
      l_endd    TYPE d,
  END OF s_data,

gt_data LIKE TABLE OF s_data WITH HEADER LINE.

START-OF-SELECTION.

  CLEAR: gv_mnth, gv_year.
  LOOP AT so_prd.

* Проверяем что заданные даты не равны
    IF so_prd-low <> so_prd-high.

* Проверяем что диапазон
      IF so_prd-OPTION = 'BT'.

* Вычисляем количество месяцев
        mnth_begda = so_prd-low+4(2).
        mnth_endda = so_prd-high+4(2).

        n = mnth_endda - mnth_begda + 1.
* Цикл по месяцам
        DO n  TIMES.

          gv_year = so_prd-low(4).

          IF gv_mnth IS INITIAL.
            gv_mnth = so_prd-low+4(2).
          ENDIF.

          CLEAR: l_endd, l_begd.
* Заполняем начальную дату месяца
          CONCATENATE gv_year gv_mnth '01' INTO l_begd.
* Находим последнюю дату месяца
          CALL FUNCTION 'MM_LAST_DAY_OF_MONTHS'
            EXPORTING
              day_in            = l_begd
            IMPORTING
              last_day_of_month = l_endd
            EXCEPTIONS
              day_in_no_date    = 1
              OTHERS            = 2.

          IF sy-subrc <> 0.
            MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
          ENDIF.


          gt_data-l_begd = l_begd.
          gt_data-l_endd = l_endd.
* Добавляем даты в таблицу
          APPEND: gt_data.

* Переходим к следующему месяцу
          gv_mnth = gv_mnth + '1'.
* Добавляем потерянный ноль
          CONCATENATE '0' gv_mnth INTO gv_mnth.

        ENDDO.

      ENDIF.
    ENDIF.

  ENDLOOP.
Back to top
View user's profile Send private message
Tomatos
Участник
Участник


Age: 38
Joined: 20 Sep 2010
Posts: 24

PostPosted: Wed Apr 18, 2012 11:39 am    Post subject: Reply with quote

Добрый день!

Организовал следующим образом:

По таблице MKPF выбираю документы, по дате, введенной в SELECT-OPTOINS во внутреннюю таблицу (поля MBLNR, MJAHR, BUDAT), после этого во внутренней таблице через Loop выделяю месяц в отдельное поле. В результате документы можно "разбить" по месяцам.
Back to top
View user's profile Send private message
Удав
Гуру
Гуру


Age: 48
Joined: 25 Jan 2008
Posts: 580
Location: Москва

PostPosted: Wed Apr 18, 2012 12:39 pm    Post subject: Reply with quote

Предлагаю свой алгоритм деления дат по периодам. Он может делить период дат (в данном случае - timestamp, но это не важно) в разрезе любых периодов, описанных в настройке вариантов финансового года (транзакция OB29)
Code:
*&---------------------------------------------------------------------*
*&      Form  GET_PERIODS
*&---------------------------------------------------------------------*
* Получение периодов последнего изменения документа
*----------------------------------------------------------------------*
*      -->PT_ZZTIMESTAMP - входной параметр ZZTIMESTAMP
*      -->PT_PERIODS     - выходная таблица периодов
*      -->VALUE(P_PERIV) - тип периода
*----------------------------------------------------------------------*
FORM get_periods  TABLES pt_zztimestamp STRUCTURE gs_periods
                         pt_periods STRUCTURE gs_periods
                  USING value(p_periv) TYPE t009-periv.

  CONSTANTS: c_first_zztimestamp TYPE likp-zztimestamp VALUE
  '20051231235959',
             c_first_time TYPE sy-uzeit VALUE '000000',
             c_last_time  TYPE sy-uzeit VALUE '235959'.
  DATA: ls_periods LIKE LINE OF pt_periods,
        lv_low_year TYPE t009b-bdatj,
        lv_low_poper TYPE t009b-poper,
        lv_high_year TYPE t009b-bdatj,
        lv_high_poper TYPE t009b-poper,
        lv_first_date TYPE sy-datum,
        lv_last_date TYPE sy-datum,
        ls_t009 TYPE t009.

  FIELD-SYMBOLS: <fs_zztimestamp> LIKE LINE OF pt_zztimestamp.

  DEFINE _date_to_period.
    lv_last_date = <fs_zztimestamp>-&1(8).
    call function 'DATE_TO_PERIOD_CONVERT'
      exporting
        i_date               = lv_last_date
*       I_MONMIT             = 00
        i_periv              = p_periv
     importing
       e_buper              = lv_&1_poper
       e_gjahr              = lv_&1_year
     exceptions
       input_false          = 1
       t009_notfound        = 2
       t009b_notfound       = 3
       others               = 4.
    if sy-subrc <> 0.
      message id sy-msgid type sy-msgty number sy-msgno
        with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        raising  error_passed_to_mess_handler.
    endif.

  END-OF-DEFINITION.

  DEFINE _period_to_date.
    call function '&1_DAY_IN_PERIOD_GET'
      exporting
        i_gjahr              = lv_low_year
*     I_MONMIT             = 00
        i_periv              = p_periv
        i_poper              = lv_low_poper
     importing
       e_date               = lv_&1_date
     exceptions
       others               = 4.
    if sy-subrc <> 0.
      message id sy-msgid type sy-msgty number sy-msgno
        with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        raising  error_passed_to_mess_handler.
    endif.
  END-OF-DEFINITION.

  CALL FUNCTION 'GET_PERIOD_VERSION'
    EXPORTING
      i_periv                              = p_periv
*     I_XTEXTS                             = ' '
*     I_SPRAS                              = SY-LANGU
   IMPORTING
     e_t009                               = ls_t009
*     E_T009T                              =
   EXCEPTIONS
     OTHERS                               = 3.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      RAISING  error_passed_to_mess_handler.
  ENDIF.

  IF pt_zztimestamp IS INITIAL.
"Если период изменения не заполнен, считаем равным его от начала времен
"до текущей даты
    ls_periods-sign = 'I'.
    ls_periods-option = 'BT'.
    CONCATENATE sy-datum c_last_time INTO ls_periods-high.
    APPEND ls_periods TO pt_zztimestamp.
  ENDIF.
  REFRESH pt_periods.
  LOOP AT pt_zztimestamp ASSIGNING <fs_zztimestamp>.
    ls_periods = <fs_zztimestamp>.
    IF <fs_zztimestamp>-low IS INITIAL. "Начальная дата не задана
      ls_periods-high = c_first_zztimestamp.
      APPEND ls_periods TO pt_periods.
      lv_first_date = c_first_zztimestamp(8).
      ADD 1 TO lv_first_date.
      CONCATENATE lv_first_date c_first_time INTO <fs_zztimestamp>-low.
    ENDIF.

    _date_to_period: low, high.
* Цикл по периодам
    WHILE lv_low_year < lv_high_year OR ( lv_low_year = lv_high_year
                                    AND lv_low_poper <= lv_high_poper ).
      _period_to_date: first, last.
      ls_periods-sign = 'I'.
      ls_periods-option = 'BT'.
      IF sy-index > 1 AND lv_first_date >= <fs_zztimestamp>-low.
        CONCATENATE lv_first_date c_first_time INTO ls_periods-low.
      ELSE.
        ls_periods-low = <fs_zztimestamp>-low.
      ENDIF.
      IF lv_low_year <> lv_high_year OR lv_low_poper <> lv_high_poper.
        CONCATENATE lv_last_date c_last_time INTO ls_periods-high.
      ELSE.
        ls_periods-high = <fs_zztimestamp>-high.
      ENDIF.
      APPEND ls_periods TO pt_periods.
      IF lv_low_poper = ls_t009-anzbp.
        lv_low_poper = '001'.
        ADD 1 TO lv_low_year.
      ELSE.
        ADD 1 TO lv_low_poper.
      ENDIF.
    ENDWHILE.
  ENDLOOP.
ENDFORM.                    " GET_PERIODS

_________________
С уважением,
Удав.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ABAP All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG.
SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG.
Every effort is made to ensure content integrity. Use information on this site at your own risk.