Номер дня недели в месяце

В продолжение темы "Добавить к дате рабочие дни в запросе" (http://infostart.ru/public/166349/) — у клиента была самописная конфигурация, в которой график посещения торговой точки указывался в виде дней недели (например, вторник и пятница), а нужно было сделать так, чтобы указывался ещё и номер этого дня в месяце (например, третий четверг).

Бывает в самописных конфигурациях делают некое расписание, например, посещения торговых точек. Простейшим расписанием может быть, например, указание дня недели и какого-то ещё номера — номера недели в месяце или номера дня недели в месяце.

Первый вариант реализуется в запросе на проверку попадания торговой точки в расписание очень просто — решается формулой типа НЕДЕЛЯ(ТекущаяДата) — НЕДЕЛЯ(НАЧАЛОПЕРИОДА(ТекущаяДата, МЕСЯЦ)) + 1. Тогда описание расписания будет типа «понедельник первой недели и пятница третей недели». Но на слух, без просмотра календаря, такое расписание воспринимается не очень хорошо — например, первая неделя января начинается со вторника, т.е. понедельника в ней просто нет, а всего недель в месяце может быть аж 6, при этом в двух неделях будет по одному и по два дня. Такое решение просто будет путать пользователя.

Более понятно будет, если указать номер дня недели в месяце, тогда расписание будет звучать типа «первый понедельник и третья пятница». Вот для этого случая написал запрос. Собственно, цели статьи: 1. не ломать голову над этой задачей другому, 2. может быть кто-то предложит более красивое решение. 

В запрос добавлена таблица с названиями дней недели. Параметр &Дата1 должен начинаться с начала месяца. 

 

ВЫБРАТЬ
"Понедельник" КАК Название,
1 КАК Номер
ПОМЕСТИТЬ НазванияДней

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
"Вторник",
2

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
"Среда",
3

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
"Четверг",
4

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
"Пятница",
5

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
"Суббота",
6

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
"Воскресенье",
7
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Календарь.ДатаКалендаря КАК Дата,
ДЕНЬНЕДЕЛИ(Календарь.ДатаКалендаря) КАК ДеньНедели,
НазванияДней.Название,
СУММА(1) КАК НомерДняВМесяце
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Календарь
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Календарь1
ПО (Календарь.ДатаКалендаря МЕЖДУ &Дата1 И &Дата2)
И (Календарь1.ДатаКалендаря МЕЖДУ &Дата1 И &Дата2)
И (ДЕНЬНЕДЕЛИ(Календарь.ДатаКалендаря) = ДЕНЬНЕДЕЛИ(Календарь1.ДатаКалендаря))
И Календарь.ДатаКалендаря >= Календарь1.ДатаКалендаря
И (НАЧАЛОПЕРИОДА(Календарь.ДатаКалендаря, МЕСЯЦ) = НАЧАЛОПЕРИОДА(Календарь1.ДатаКалендаря, МЕСЯЦ))
ВНУТРЕННЕЕ СОЕДИНЕНИЕ НазванияДней КАК НазванияДней
ПО (ДЕНЬНЕДЕЛИ(Календарь.ДатаКалендаря) = НазванияДней.Номер)

СГРУППИРОВАТЬ ПО
Календарь.ДатаКалендаря,
НазванияДней.Название

УПОРЯДОЧИТЬ ПО
Дата
 
 
Ну и кусок результата:
 
       
Дата ДеньНедели Название НомерДняВМесяце  
01.12.2012 6 Суббота 1  
02.12.2012 7 Воскресенье 1  
03.12.2012 1 Понедельник 1  
04.12.2012 2 Вторник 1  
05.12.2012 3 Среда 1  
06.12.2012 4 Четверг 1  
07.12.2012 5 Пятница 1  
08.12.2012 6 Суббота 2  
09.12.2012 7 Воскресенье 2  
10.12.2012 1 Понедельник 2  
11.12.2012 2 Вторник 2  
12.12.2012 3 Среда 2  
13.12.2012 4 Четверг 2  
14.12.2012 5 Пятница 2  
15.12.2012 6 Суббота 3  
16.12.2012 7 Воскресенье 3  
17.12.2012 1 Понедельник 3  
18.12.2012 2 Вторник 3  
19.12.2012 3 Среда 3  
20.12.2012 4 Четверг 3  
21.12.2012 5 Пятница 3  
22.12.2012 6 Суббота 4  
23.12.2012 7 Воскресенье 4  
 

10 Comments

  1. DoctorRoza

    Ну и хрень! 🙂 Чеслово, но забавная!

    Reply
  2. akomar

    Номер недели в месяце, или день недели, чтото я запутался.

    Reply
  3. Hany

    ОПА! Классная задачка! Спасибо! Встряхнула в сонные дни новогодних праздников…

    Посоревнуемся?:)

    У меня запрос меньше:)

    ВЫБРАТЬ
    Календарь.ДатаКалендаря КАК Дата,
    (ВЫРАЗИТЬ((РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Календарь.ДатаКалендаря, МЕСЯЦ), Календарь.ДатаКалендаря, ДЕНЬ) + 1) / 7 — 0.6 КАК ЧИСЛО(15, 0))) + 1 КАК НомерДняВМесяце,
    ДЕНЬНЕДЕЛИ(Календарь.ДатаКалендаря) КАК ДеньНедели
    ИЗ
    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Календарь
    
    ГДЕ
    Календарь.ДатаКалендаря МЕЖДУ &Дата1 И &Дата2
    
    УПОРЯДОЧИТЬ ПО
    Дата
    

    Показать

    П.С. Названия дней недели я не выводила для наглядности, и так ясно, что для этого, как у вас нужно соединить с вашей временной таблицей «НазванияДней» по полю ДеньНедели.

    Акент делаю на вычисление поля НомерДняВМесяце без внутренних соединений.

    Reply
  4. INTECH1

    Hany, да, здорово, победила!!! Хорошо, что выложил задачку, не подумал бы её по другому решать.

    Reply
  5. INTECH1

    (2) akomar, привет, ну если вкратце — говорим типа «третий вторник месяца» — вот и нужно узнать, какой это вторник по некой дате.

    Reply
  6. INTECH1

    (3) Hany, в общем, пользуясь вашей идеей, наверное, окончательный вариант будет:

    ВЫБРАТЬ

    Календарь.ДатаКалендаря КАК Дата,

    ВЫРАЗИТЬ(ДЕНЬ(Календарь.ДатаКалендаря) / 7 + 0.4 КАК ЧИСЛО(15, 0)) КАК НомерДняВМесяце,

    ДЕНЬНЕДЕЛИ(Календарь.ДатаКалендаря) КАК ДеньНедели

    ИЗ

    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Календарь

    ГДЕ

    Календарь.ДатаКалендаря МЕЖДУ &Дата1 И &Дата2

    УПОРЯДОЧИТЬ ПО

    Дата

    Reply
  7. Boroda

    Спасибо! Интересно! Думаю, в работе пригодится….

    Reply
  8. mchammer4

    а неделя месяца как будет?

    Reply
  9. INTECH1

    (8) mchammer4, Неделя(Дата) — Неделя(НачалоПериода(Дата, Месяц)), как-то так

    Reply
  10. NAKIS

    Чем только люди не занимаются, чтобы не работать (с)

    Интересная статья — может и пригодиться) Надо взять на заметку))

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *