Имя: Пароль:
1C
1С v8
v8: Допилил генерацию рядов дат в интервале запросом для СКД и все такое
0 vmv
 
23.10.12
19:41
с периодичностью (месяц, квартал, ...)


//
// Описание: Метод позволяет по переданным параметрам ДатаН, ДатаК и Периодчность(день, месяц, квартал...)
// получать полную таблицу границ периодов с заданной периодичностью.
//
// Варианты тестового вызова:
//
// Запрос = Add_ComM_ОтчетыС.ПолучитьЗапросФинансовыхПериодовВИнтервале(Дата(2010, 8, 3), Дата(2012, 12, 21), Перечисления.Периодичность.Квартал);
// Запрос.Выполнить().Выгрузить().ВыбратьСтроку("Квартал");
// Запрос = Add_ComM_ОтчетыС.ПолучитьЗапросФинансовыхПериодовВИнтервале(Дата(2010, 8, 3), Дата(2012, 12, 21), Перечисления.Периодичность.Месяц);
// Запрос.Выполнить().Выгрузить().ВыбратьСтроку("Месяц");
// Запрос = Add_ComM_ОтчетыС.ПолучитьЗапросФинансовыхПериодовВИнтервале(Дата(2010, 8, 3), Дата(2012, 12, 21), Перечисления.Периодичность.Полугодие);
// Запрос.Выполнить().Выгрузить().ВыбратьСтроку("Полугодие");
//
// Ипользование этого запроса в СКД где есть таблицы с разворотом по периодам (день, месяц, квартал)
// позволит вообще не использовать детализацют дат в СКД, что и не всегда там работает.
//
// Описание применения в СКД
// 1. Копируем текст этого запроса в заголовочные пакеты источника данных запроса СКД
// 2. Помещаем последний запрос из этого пакета во временную таблицу и индексируем по полю ДатаНП, ДатаКП если по ним будут соединения
// 3. В следующем пакете соединяем полученную Вт в том же запросе с пакетом данных (пакет запроса из регистров сведений, оборотов и т.д.)
// 4. в настройке СДД настраиваем группировки по ДатаНП или ДатаКП, отключив все расширения дат
//
Функция ПолучитьЗапросФинансовыхПериодовВИнтервале(ДатаН, ДатаК, Периодичность) Экспорт
           
   ЗапросТекст =
   "ВЫБРАТЬ
   |    ДОБАВИТЬКДАТЕ(&ДатаН, ДЕНЬ, aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d) КАК ДатаДня
   |ПОМЕСТИТЬ ВтДатыВИнтервале
   |ИЗ
   |    (ВЫБРАТЬ
   |        0 КАК a
   |    
   |    ОБЪЕДИНИТЬ
   |    
   |    ВЫБРАТЬ
   |        1
   |    
   |    ОБЪЕДИНИТЬ
   |    
   |    ВЫБРАТЬ
   |        2
   |    
   |    ОБЪЕДИНИТЬ
   |    
   |    ВЫБРАТЬ
   |        3
   |    
   |    ОБЪЕДИНИТЬ
   |    
   |    ВЫБРАТЬ
   |        4
   |    
   |    ОБЪЕДИНИТЬ
   |    
   |    ВЫБРАТЬ
   |        5
   |    
   |    ОБЪЕДИНИТЬ
   |    
   |    ВЫБРАТЬ
   |        6
   |    
   |    ОБЪЕДИНИТЬ
   |    
   |    ВЫБРАТЬ
   |        7
   |    
   |    ОБЪЕДИНИТЬ
   |    
   |    ВЫБРАТЬ
   |        8
   |    
   |    ОБЪЕДИНИТЬ
   |    
   |    ВЫБРАТЬ
   |        9) КАК aa
   |        ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
   |            0 КАК b
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            1
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            2
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            3
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            4
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            5
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            6
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            7
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            8
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            9) КАК bb
   |        ПО (ИСТИНА)
   |        ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
   |            0 КАК c
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            1
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            2
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            3
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            4
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            5
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            6
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            7
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            8
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            9) КАК cc
   |        ПО (ИСТИНА)
   |        ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
   |            0 КАК d
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            1
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            2
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            3
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            4
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            5
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            6
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            7
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            8
   |        
   |        ОБЪЕДИНИТЬ
   |        
   |        ВЫБРАТЬ
   |            9) КАК dd
   |        ПО (ИСТИНА)
   |ГДЕ
   |    aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d <= РАЗНОСТЬДАТ(&ДатаН, &ДатаК, ДЕНЬ)
   |;
   |
   |////////////////////////////////////////////////////////////////////////////////
   |ВЫБРАТЬ РАЗЛИЧНЫЕ
   |    ВЫБОР
   |        КОГДА &Периодичность = &ПериодичностьДень
   |            ТОГДА НАЧАЛОПЕРИОДА(ВтДатыВИнтервале.ДатаДня, ДЕНЬ)
   |        КОГДА &Периодичность = &ПериодичностьМесяц
   |            ТОГДА НАЧАЛОПЕРИОДА(ВтДатыВИнтервале.ДатаДня, МЕСЯЦ)
   |        КОГДА &Периодичность = &ПериодичностьКвартал
   |            ТОГДА НАЧАЛОПЕРИОДА(ВтДатыВИнтервале.ДатаДня, КВАРТАЛ)
   |        КОГДА &Периодичность = &ПериодичностьПолугодие
   |            ТОГДА НАЧАЛОПЕРИОДА(ВтДатыВИнтервале.ДатаДня, ПОЛУГОДИЕ)
   |        КОГДА &Периодичность = &ПериодичностьГод
   |            ТОГДА НАЧАЛОПЕРИОДА(ВтДатыВИнтервале.ДатаДня, ГОД)
   |        ИНАЧЕ НАЧАЛОПЕРИОДА(&ДатаН, ДЕНЬ)
   |    КОНЕЦ КАК ДатаНП,
   |    ВЫБОР
   |        КОГДА &Периодичность = &ПериодичностьДень
   |            ТОГДА КОНЕЦПЕРИОДА(ВтДатыВИнтервале.ДатаДня, ДЕНЬ)
   |        КОГДА &Периодичность = &ПериодичностьМесяц
   |            ТОГДА КОНЕЦПЕРИОДА(ВтДатыВИнтервале.ДатаДня, МЕСЯЦ)
   |        КОГДА &Периодичность = &ПериодичностьКвартал
   |            ТОГДА КОНЕЦПЕРИОДА(ВтДатыВИнтервале.ДатаДня, КВАРТАЛ)
   |        КОГДА &Периодичность = &ПериодичностьПолугодие
   |            ТОГДА КОНЕЦПЕРИОДА(ВтДатыВИнтервале.ДатаДня, ПОЛУГОДИЕ)
   |        КОГДА &Периодичность = &ПериодичностьГод
   |            ТОГДА КОНЕЦПЕРИОДА(ВтДатыВИнтервале.ДатаДня, ГОД)
   |        ИНАЧЕ КОНЕЦПЕРИОДА(&ДатаК, ДЕНЬ)
   |    КОНЕЦ КАК ДатаКП
   |ПОМЕСТИТЬ ВтГраницыПериодов
   |ИЗ
   |    ВтДатыВИнтервале КАК ВтДатыВИнтервале
   |;
   |
   |////////////////////////////////////////////////////////////////////////////////
   |УНИЧТОЖИТЬ ВтДатыВИнтервале
   |;
   |
   |////////////////////////////////////////////////////////////////////////////////
   |ВЫБРАТЬ
   |    ВЫБОР
   |        КОГДА &Периодичность = &ПериодичностьМесяц
   |                ИЛИ &Периодичность = &ПериодичностьКвартал
   |                ИЛИ &Периодичность = &ПериодичностьПолугодие
   |                ИЛИ &Периодичность = &ПериодичностьГод
   |            ТОГДА ВЫБОР
   |                    КОГДА ВтГраницыПериодов.ДатаНП < &ДатаН
   |                        ТОГДА ВЫБОР
   |                                КОГДА НАЧАЛОПЕРИОДА(&ДатаН, МЕСЯЦ) < &ДатаН
   |                                    ТОГДА НАЧАЛОПЕРИОДА(&ДатаН, ДЕНЬ)
   |                                ИНАЧЕ НАЧАЛОПЕРИОДА(&ДатаН, МЕСЯЦ)
   |                            КОНЕЦ
   |                    ИНАЧЕ ВтГраницыПериодов.ДатаНП
   |                КОНЕЦ
   |        ИНАЧЕ ВтГраницыПериодов.ДатаНП
   |    КОНЕЦ КАК ДатаНП,
   |    ВЫБОР
   |        КОГДА &Периодичность = &ПериодичностьМесяц
   |                ИЛИ &Периодичность = &ПериодичностьКвартал
   |                ИЛИ &Периодичность = &ПериодичностьПолугодие
   |                ИЛИ &Периодичность = &ПериодичностьГод
   |            ТОГДА ВЫБОР
   |                    КОГДА ВтГраницыПериодов.ДатаКП > &ДатаК
   |                        ТОГДА ВЫБОР
   |                                КОГДА КОНЕЦПЕРИОДА(&ДатаК, МЕСЯЦ) > &ДатаК
   |                                    ТОГДА КОНЕЦПЕРИОДА(&ДатаК, ДЕНЬ)
   |                                ИНАЧЕ КОНЕЦПЕРИОДА(&ДатаК, МЕСЯЦ)
   |                            КОНЕЦ
   |                    ИНАЧЕ ВтГраницыПериодов.ДатаКП
   |                КОНЕЦ
   |        ИНАЧЕ ВтГраницыПериодов.ДатаКП
   |    КОНЕЦ КАК ДатаКП
   |ИЗ
   |    ВтГраницыПериодов КАК ВтГраницыПериодов";
   
   ПараметрыВЗапрос = Новый Структура;
   
   // Основные параметры запроса
   ПараметрыВЗапрос.Вставить("ДатаН", ?(ЗначениеЗаполнено(ДатаН), ДатаН, Дата(2000, 1 , 1 )));  
   ПараметрыВЗапрос.Вставить("ДатаК", ?(ЗначениеЗаполнено(ДатаК), ДатаК, Дата(2015, 12, 31)));  
   ПараметрыВЗапрос.Вставить("Периодичность", ?(ЗначениеЗаполнено(Периодичность), Периодичность, ПредопределенноеЗначение("Перечисление.Периодичность.ПустаяСсылка")));
   
   // Служебные параметры запроса, устраняющие вычисление в запросах предопределенных значений
   ПараметрыВЗапрос.Вставить("ПериодичностьДень"     , ПредопределенноеЗначение("Перечисление.Периодичность.День"));
   ПараметрыВЗапрос.Вставить("ПериодичностьМесяц"    , ПредопределенноеЗначение("Перечисление.Периодичность.Месяц"));
   ПараметрыВЗапрос.Вставить("ПериодичностьКвартал"  , ПредопределенноеЗначение("Перечисление.Периодичность.Квартал"));
   ПараметрыВЗапрос.Вставить("ПериодичностьПолугодие", ПредопределенноеЗначение("Перечисление.Периодичность.Полугодие"));
   ПараметрыВЗапрос.Вставить("ПериодичностьГод"      , ПредопределенноеЗначение("Перечисление.Периодичность.Год"));
   
   // Если Перечисление.Периодичность не существует в конфигурации, то заменить эти парметры числовыми,
   // т.е. 0 - Периодичность.День, 1 - Периодичность.Месяц и т.д.
   
   // Инициализируем переменную запроса, текст запроса и параметры запроса
   Запрос = Новый Запрос;
   Запрос.Текст = ЗапросТекст;
   Для каждого ЭлементСтруктуры Из ПараметрыВЗапрос Цикл
       Запрос.УстановитьПараметр(ЭлементСтруктуры.Ключ, ЭлементСтруктуры.Значение);
   КонецЦикла;
   
   Возврат Запрос;
   
КонецФункции

К сожалению старый известный запрос по месяцам брешет!

ВЫБРАТЬ
   0 КАК Цифра
ПОМЕСТИТЬ ВтЦифры

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   1

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   2

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   3

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   4

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   5

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   6

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   7

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   8

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   9
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   Тысячи.Цифра * 1000 + Сотни.Цифра * 100 + Десятки.Цифра * 10 + Единицы.Цифра КАК Число
ПОМЕСТИТЬ ВтСмещение
ИЗ
   ВтЦифры КАК Тысячи,
   ВтЦифры КАК Сотни,
   ВтЦифры КАК Десятки,
   ВтЦифры КАК Единицы
ГДЕ
   Тысячи.Цифра * 1000 + Сотни.Цифра * 100 + Десятки.Цифра * 10 + Единицы.Цифра <= РАЗНОСТЬДАТ(&ДатаН, &ДатаК, МЕСЯЦ)
;

////////////////////////////////////////////////////////////////////////////////
УНИЧТОЖИТЬ ВтЦифры
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ДОБАВИТЬКДАТЕ(КОНЕЦПЕРИОДА(&ДатаН, МЕСЯЦ), МЕСЯЦ, ВтСмещение.Число) КАК КонецМесяца
ПОМЕСТИТЬ ВтОкончанияМесяцев
ИЗ
   ВтСмещение КАК ВтСмещение

ИНДЕКСИРОВАТЬ ПО
   КонецМесяца
;

////////////////////////////////////////////////////////////////////////////////
УНИЧТОЖИТЬ ВтСмещение
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ВтОкончанияМесяцев.КонецМесяца КАК КонецМесяца
ИЗ
   ВтОкончанияМесяцев КАК ВтОкончанияМесяцев

УПОРЯДОЧИТЬ ПО
   КонецМесяца

если взять интервал 01.04.2012 - 30.06.2012 то 31 мая не попадавет в выборку

разбираться не стал с последним и запилил только что для любой периодчности. Можете тестить, вдруг еще где глюк
1 guevara74
 
23.10.12
19:46
Вопрос : Для чего это??? Вообщем то во всех типовых (наверное кроме УТ) есть регламентированный производственный календарь,который можно в запросах крутить как надо
2 vmv
 
23.10.12
19:48
(1) а если его нет, а если его лень заполнять, а если лень читать еще одну таблицу - ведь Пр. Кал. - это РС)

не нравиться не жри, я не заставляю)
3 vmv
 
23.10.12
19:50
(2) а если ели это отчет по прогнозированию на 5 лет вперед, будешь каледарик гнать на 5 лет вперед, а если на 10 лет.

все хватит если, мну удалился к плите
4 Новенький_2009
 
23.10.12
20:17
каждый твой пост заканчивается - я пошел жрать ;)

Займись ужо спортом!
5 hhhh
 
23.10.12
21:11
(3) ну вот здесь ты нереально лоханулся

ВЫБРАТЬ
   ДОБАВИТЬКДАТЕ(КОНЕЦПЕРИОДА(&ДатаН, МЕСЯЦ), МЕСЯЦ, ВтСмещение.Число) КАК КонецМесяца

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

То есть ты жестко задал концом месяца 30 мая.
6 vmv
 
23.10.12
22:21
(5) ага, там начало периода читать надо - исправлю, а в результирующем пакете уже вычислять конец периода от начала
7 vmv
 
23.10.12
22:23
+(6) и это тыреный запрос, я ему верил даже не читая), потом забил и написал от даты дней как в (1)
8 Новенький_2009
 
30.10.12
13:59
(7) так конечная версия есть твоего творенья?