Имя: Пароль:
1C
1С v8
Построить запрос про ближайший рабочий день
0 nesta sandro
 
26.02.16
15:09
Привет всем,

Есть РС РегламентированныйПроизводственныйКалендарь, надо только запросом получить таблицу, в которой календарный день по порядку, затем ближаший N-ый рабочий день, где N любое целое число.

Для 1 января будет день 11 января в 2016 году, для 2 января тоже и т.д. до 9 января - будет 12 января 2016 и т.д.

Помогите составить запрос, мозг сломал.
1 ObjectRelation Model
 
26.02.16
15:10
собеседование?
2 nesta sandro
 
26.02.16
15:12
типа того :)
3 Mikeware
 
26.02.16
15:13
(2) а работать как будешь?
4 mehfk
 
26.02.16
15:14
Покажи что уже написал.
5 nesta sandro
 
26.02.16
15:15
(3) в остальном все ок, просто запросы с датами не сильный конек.
6 nesta sandro
 
26.02.16
15:15
ВЫБРАТЬ
    РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК ДеньКалендаря,
    ВложенныйЗапрос.ДатаКалендаря КАК РабочийДень
ИЗ
    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            РегламентированныйПроизводственныйКалендарь.ДатаКалендаря КАК ДатаКалендаря
        ИЗ
            РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
        ГДЕ
            (РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
                    ИЛИ РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный))) КАК ВложенныйЗапрос
        ПО РегламентированныйПроизводственныйКалендарь.ДатаКалендаря = ВложенныйЗапрос.ДатаКалендаря
ГДЕ
    РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &ДатаНачала И &ДатаКонца
7 фобка
 
26.02.16
15:16
Былоб чо ломать...
Select min (rs.day) from rs as rs where rs.type = "rabo4ij" and rs.day >&day order by rs.day
8 nesta sandro
 
26.02.16
15:16
Это просто календарный день и рабочий день. Теперь как-то организовать смещение на N дней.
9 nesta sandro
 
26.02.16
15:18
да с параметром понятно все, а в таблице.
10 фобка
 
26.02.16
15:19
ну чуть сложнее в джойне виесто параметра день из первой таблицы + н-дней
11 nesta sandro
 
26.02.16
15:20
(10) не получится.
12 фобка
 
26.02.16
15:21
В джойне 1С во вложенном запросе позволяет указывать поле другой таблицы
13 nesta sandro
 
26.02.16
15:22
(12) пример? видимо не допонимаю.
14 фобка
 
26.02.16
15:25
Select t1.a t2.b from t1 t1  join (select t2.a from t2 t2 where t2.b< t1.b) t2 on t2.a = t1.a
15 фобка
 
26.02.16
15:27
select t1.a, t2.b - пропустил зпт
16 nesta sandro
 
26.02.16
15:30
(14) 1С так не может.
17 kumena
 
26.02.16
15:30
задача на 10 минут
18 фобка
 
26.02.16
15:32
(16) да брось ты
19 nesta sandro
 
26.02.16
15:36
(17) ок возможно, жду решение. спасибо.
20 kumena
 
26.02.16
15:39
(19)

ок, решение


Выбрать
    ДатаКалендаря

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

Где НачалоПериода(ДатаКалендаря, Месяц) = ДатаВремя(2016, 01, 01)

;

Выбрать
    СписокДат.ДатаКалендаря
    ,Минимум(Календарь.ДатаКалендаря) КАК РабочийДень

Из СписокДат КАК СписокДат
    Левое соединение РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Календарь
    По ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
    и СписокДат.ДатаКалендаря < Календарь.ДатаКалендаря
    
Сгруппировать по
СписокДат.ДатаКалендаря    


с тебя 500 р.
21 Alexandr_U1982
 
26.02.16
15:39
ВЫБРАТЬ
    ВсеДниКалендаря.ДатаКалендаря КАК ДеньКалендаря,
    МИНИМУМ(РабочиеДниКалендаря.ДатаКалендаря) КАК РабочийДень
ИЗ
    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК ВсеДниКалендаря
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РабочиеДниКалендаря
        ПО (РабочиеДниКалендаря.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
                ИЛИ РабочиеДниКалендаря.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный))
            И (ДОБАВИТЬКДАТЕ(ВсеДниКалендаря.ДатаКалендаря, ДЕНЬ, &КоличествоДней) <= РабочиеДниКалендаря.ДатаКалендаря)
ГДЕ
    ВсеДниКалендаря.ДатаКалендаря МЕЖДУ &ДатаНачала И &ДатаОкончания

СГРУППИРОВАТЬ ПО
    ВсеДниКалендаря.ДатаКалендаря

УПОРЯДОЧИТЬ ПО
    ДеньКалендаря
22 Alexandr_U1982
 
26.02.16
15:41
(20) Не учитываешь предпраздничные дни
23 kumena
 
26.02.16
15:43
(22) сам догадается, на халяву еще и со всеми проверками жирно будет.
24 фобка
 
26.02.16
15:49
(14) немного не так написал, неудобно с телефона

(16)
ВЫБРАТЬ
Р1.ДатаКалендаря,
Р2.ДатаКалендаря,
ИЗ
   РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Р1
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Р2
ПО (Р2.ДатаКалендаря В
ВЫБРАТЬ МИНИМУМ(Р3.ДатаКалендаря) КАК ДатаКалендаря
ИЗ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Р3
ГДЕ
Р3.ВидДня = &Рабочий
И Р3.ДатаКалендаря > ДОБАВИТЬКДАТЕ(Р1.ДатаКалендаря, ДЕНЬ, &КолДней)))
25 nesta sandro
 
26.02.16
16:16
(24) (21) (20) :))) я, видимо, запаренный делаю. У меня был вариант, как 21, только с ВсеДниКалендаря.ДатаКалендаря<=ДобавитьКДате(РабочиеДниКалендаря,День,-3). Потом паническую атаку словил и начал сначала с того, что сначала видели.

Спасибо, коллеги. :))))
26 Alexandr_U1982
 
26.02.16
16:20
(25) Еще вот так можно:

ВЫБРАТЬ
    ВсеДниКалендаря.ДатаКалендаря КАК ДеньКалендаря,
    МИНИМУМ(РабочиеДниКалендаря.ДатаКалендаря) КАК РабочийДень
ПОМЕСТИТЬ ВТ_Данные
ИЗ
    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК ВсеДниКалендаря
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РабочиеДниКалендаря
        ПО (РабочиеДниКалендаря.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
                ИЛИ РабочиеДниКалендаря.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный))
            И ВсеДниКалендаря.ДатаКалендаря <= РабочиеДниКалендаря.ДатаКалендаря
ГДЕ
    ВсеДниКалендаря.ДатаКалендаря МЕЖДУ &ДатаНачала И &ДатаОкончания

СГРУППИРОВАТЬ ПО
    ВсеДниКалендаря.ДатаКалендаря
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВсеДниКалендаря.ДеньКалендаря КАК ДеньКалендаря,
    РабочиеДниКалендаря.РабочийДень
ИЗ
    ВТ_Данные КАК ВсеДниКалендаря
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Данные КАК РабочиеДниКалендаря
        ПО (ВсеДниКалендаря.РабочийДень = ДОБАВИТЬКДАТЕ(РабочиеДниКалендаря.ДеньКалендаря, ДЕНЬ, -&КоличествоДней))

УПОРЯДОЧИТЬ ПО
    ДеньКалендаря

Это если требуется показать N-й рабочий день
27 aleks_default
 
26.02.16
16:25
хорошо на мисте, работодатели решают задачки своих же соискателей.
28 alle68
 
27.02.16
07:16
Пока верного решения (для N >= 2) нет.
29 Alexandr_U1982
 
04.03.16
10:49
(28) Да неужели? ))
30 cathode
 
04.03.16
14:11
(29) Точно, для 25.01.2016 и N = 5 не работает.
31 cathode
 
04.03.16
14:21
(0) Предлагаю свой вариант. Он работает, но может быть неэффективным для больших N.

ВЫБРАТЬ
    К.ДатаКалендаря КАК Дата
    , МИНИМУМ(ПР.ДатаКалендаря) КАК НачалоИнтервала
        // Смысл манипуляции: превратить рабочие дни в календарные
        // и добавить максимальный непрерывный нерабочий период, который
        // может быть с учетом праздников. Округлить в большую сторону.
    , ДОБАВИТЬКДАТЕ(К.ДатаКалендаря, ДЕНЬ, ВЫРАЗИТЬ((&КоличествоДней * 7 / 5) + 11 КАК ЧИСЛО(10, 0))) КАК КонецИнтервала
ПОМЕСТИТЬ
    ВТ_ИнтервалыРабочихДней
ИЗ
    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК К
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК ПР
            // Если ближайшим рабочим днем для рабочего дня считается следующий, ставим >
            // Если ближайшим рабочим днем для рабочего дня считается текущий, ставим >=
        ПО ПР.ДатаКалендаря > К.ДатаКалендаря
            И ПР.ВидДня В (
                ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
                , ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный)
            )
ГДЕ
    К.ДатаКалендаря МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
    К.ДатаКалендаря
ИНДЕКСИРОВАТЬ ПО
    Дата
;
    
ВЫБРАТЬ
    ИР.Дата КАК Дата
    , РД.ДатаКалендаря КАК РабочийДень
ПОМЕСТИТЬ
    ВТ_РабочиеДни
ИЗ
    ВТ_ИнтервалыРабочихДней КАК ИР
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РД
        ПО РД.ДатаКалендаря >= ИР.НачалоИнтервала
            И РД.ДатаКалендаря <= ИР.КонецИнтервала
            И РД.ВидДня В (
                ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
                , ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный)
            )
ИНДЕКСИРОВАТЬ ПО
    Дата
    , РабочийДень
;

ВЫБРАТЬ
    РД1.Дата КАК Дата
    , РД1.РабочийДень КАК РабочийДень
ИЗ
    ВТ_РабочиеДни КАК РД1
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_РабочиеДни КАК РД2
        ПО РД2.Дата = РД1.Дата
            И РД2.РабочийДень <= РД1.РабочийДень
СГРУППИРОВАТЬ ПО
    РД1.Дата
    , РД1.РабочийДень
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(*) = &КоличествоДней
УПОРЯДОЧИТЬ ПО
    Дата