Получить даты за период в запросе
Теги: 1С,ТаблицаЗначений,Период,Запрос,Шаг,Результат запроса,Менеджер временных таблиц,МенеджерВременныхТаблиц,Таблица значений,Дата

Генерация списка дат за период с настраиваемым шагом в днях в запросе

# Код реализации

```1c
// Возвращает текст запроса, или добавляет запрос во временную таблицу, или возвращает результат запроса, или таблицу значений с результатом запроса.
// Следует указать истина только в одном из следующих параметров:
// - ПолучитьТекстЗапроса
// - ПолучитьРезультатЗапроса
// - ПолучитьТаблицуЗначений.
//
// Параметры:
//  НачалоПериода              - Дата - начало периода отсчета.
//  КонецПериода               - Дата - конец периода отсчета включительно.
//  Шаг                        - Число - шаг вывода дат в днях.
//  ПолучитьПоследнююДату      - Булево - признак вывода последнего дня, если тот не попадает по шагу.
//  ИмяКолонкиПериод           - Строка - имя колонки с датами.
//  ПолучитьКолонкуШаг         - Булево - признак получения колонки шага, используемой для отладки.
//  ИмяКолонкиШаг              - Строка - имя колонки с шагом.
//  ПолучитьТекстЗапроса       - Булево - возврат текста запроса.
//  ДобавитьВоВременныеТаблицы - Булево - добавление запроса во временную таблицу.
//  МенеджерВременныхТаблиц    - МенеджерВременныхТаблиц - менеджер временных таблиц.
//  ИмяВременнойТаблицы        - Строка - имя временной таблицы.
//  ПолучитьРезультатЗапроса   - Булево - получить результат запроса.
//  ПолучитьТаблицуЗначений    - Булево - получить таблицу значений с результатом запроса.
//  УничтожитьВТ               - Булево - если истина, в конце запроса будут уничтеженны промежуточные временные таблицы.
//
// Возвращаемое значение:
//  - Строка            - если ПолучитьТекстЗапроса истина.
//	- Временная таблица - если ДобавитьВоВременныеТаблицы истина.
//	- Результат запрос  - если ПолучитьРезультатЗапроса истина.
//	- Таблица значений  - если ПолучитьТаблицуЗначений истина.
//
Функция ПолучитьДатыЗаПериодВЗапросе(НачалоПериода = Неопределено, КонецПериода = Неопределено, Шаг = 1, ПолучитьПоследнююДату = Ложь,
										ИмяКолонкиПериод = "Период", ПолучитьКолонкуШаг = Ложь, ИмяКолонкиШаг = "Шаг",
										ПолучитьТекстЗапроса = Ложь, ДобавитьВоВременныеТаблицы = Ложь, МенеджерВременныхТаблиц = Неопределено,
										ИмяВременнойТаблицы = "#ДатыЗаПериод", ПолучитьРезультатЗапроса = Ложь, ПолучитьТаблицуЗначений = Ложь,
										УничтожитьВТ = Истина) Экспорт

	ТекстЗапроса =
		"ВЫБРАТЬ 0 КАК Цифра
		|ПОМЕСТИТЬ Цифры
		|ОБЪЕДИНИТЬ ВЫБРАТЬ 1
		|ОБЪЕДИНИТЬ ВЫБРАТЬ 2
		|ОБЪЕДИНИТЬ ВЫБРАТЬ 3
		|ОБЪЕДИНИТЬ ВЫБРАТЬ 4
		|ОБЪЕДИНИТЬ ВЫБРАТЬ 5
		|ОБЪЕДИНИТЬ ВЫБРАТЬ 6
		|ОБЪЕДИНИТЬ ВЫБРАТЬ 7
		|ОБЪЕДИНИТЬ ВЫБРАТЬ 8
		|ОБЪЕДИНИТЬ ВЫБРАТЬ 9
		|;
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, СписокДней.Дней) КАК Период
		|ПОМЕСТИТЬ НужныйПериод
		|ИЗ
		|	(ВЫБРАТЬ
		|		СотниТысяч.Цифра * 100000 + ДесяткиТысяч.Цифра * 10000 + Тысячи.Цифра * 1000 + Сотни.Цифра * 100 + Десятки.Цифра * 10 + Единицы.Цифра КАК Дней
		|	ИЗ
		|		Цифры КАК СотниТысяч
		|			ВНУТРЕННЕЕ СОЕДИНЕНИЕ Цифры КАК ДесяткиТысяч
		|				ВНУТРЕННЕЕ СОЕДИНЕНИЕ Цифры КАК Тысячи
		|					ВНУТРЕННЕЕ СОЕДИНЕНИЕ Цифры КАК Сотни
		|						ВНУТРЕННЕЕ СОЕДИНЕНИЕ Цифры КАК Десятки
		|							ВНУТРЕННЕЕ СОЕДИНЕНИЕ Цифры КАК Единицы
		|							ПО (Десятки.Цифра * 10 <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ))
		|								И (Единицы.Цифра <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ))
		|						ПО (Сотни.Цифра * 100 <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ))
		|					ПО (Тысячи.Цифра * 1000 <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ))
		|				ПО (ДесяткиТысяч.Цифра * 10000 <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ))
		|			ПО (СотниТысяч.Цифра * 100000 <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ))
		|	ГДЕ
		|		СотниТысяч.Цифра * 100000 + ДесяткиТысяч.Цифра * 10000 + Тысячи.Цифра * 1000 + Сотни.Цифра * 100 + Десятки.Цифра * 10 + Единицы.Цифра <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ)) КАК СписокДней
		|;
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	НужныйПериод1.Период КАК Период,
		|	СУММА(1) + (&Шаг - 1) КАК Шаг
		|ПОМЕСТИТЬ ПериодДоОбрезания
		|ИЗ
		|	НужныйПериод КАК НужныйПериод1
		|		ЛЕВОЕ СОЕДИНЕНИЕ НужныйПериод КАК НужныйПериод2
		|		ПО НужныйПериод1.Период >= НужныйПериод2.Период
		|
		|СГРУППИРОВАТЬ ПО
		|	НужныйПериод1.Период
		|;
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ПериодДоОбрезания.Период КАК Период,
		|	ПериодДоОбрезания.Шаг КАК Шаг
		|ПОМЕСТИТЬ ПериодПлюсПоследняяДата
		|ИЗ
		|	ПериодДоОбрезания КАК ПериодДоОбрезания
		|ГДЕ
		|	ПериодДоОбрезания.Шаг / &Шаг = (ВЫРАЗИТЬ(ПериодДоОбрезания.Шаг / &Шаг КАК ЧИСЛО(10, 0)))
		|
		|СГРУППИРОВАТЬ ПО
		|	ПериодДоОбрезания.Период,
		|	ПериодДоОбрезания.Шаг
		|
		|ОБЪЕДИНИТЬ ВСЕ
		|
		|ВЫБРАТЬ
		|	&КонецПериода,
		|	NULL
		|;
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ПериодПлюсПоследняяДата.Период КАК " + ИмяКолонкиПериод
		 +
		 	?(ПолучитьКолонкуШаг,",
								 |	СУММА(ПериодПлюсПоследняяДата.Шаг) КАК " + ИмяКолонкиШаг, "")
		+
			?(ДобавитьВоВременныеТаблицы, "
										  |ПОМЕСТИТЬ " + ИмяВременнойТаблицы, "")
		+
		"
		|ИЗ
		|	ПериодПлюсПоследняяДата КАК ПериодПлюсПоследняяДата
		|"
		 +
		    ?(ПолучитьПоследнююДату,"ГДЕ
									|    НЕ ПериодПлюсПоследняяДата.Шаг ЕСТЬ NULL
									|", "")
		 +
		"СГРУППИРОВАТЬ ПО
		|	ПериодПлюсПоследняяДата.Период
		|"
		 +
		 	?(УничтожитьВТ, ";
							|////////////////////////////////////////////////////////////////////////////////
							|УНИЧТОЖИТЬ Цифры
							|;
							|////////////////////////////////////////////////////////////////////////////////
							|УНИЧТОЖИТЬ НужныйПериод
							|;
							|////////////////////////////////////////////////////////////////////////////////
							|УНИЧТОЖИТЬ ПериодДоОбрезания
							|;
							|////////////////////////////////////////////////////////////////////////////////
							|УНИЧТОЖИТЬ ПериодПлюсПоследняяДата ", "");

	Если ПолучитьТекстЗапроса Тогда
		Возврат ТекстЗапроса;
	КонецЕсли;

	Если НачалоПериода = Неопределено Тогда
		НачалоПериода = ТекущаяДатаСеанса();
	КонецЕсли;

	Если КонецПериода = Неопределено Тогда
		КонецПериода = ТекущаяДатаСеанса();
	КонецЕсли;

	Запрос       = Новый Запрос;
	Запрос.Текст = ТекстЗапроса;

	Если ДобавитьВоВременныеТаблицы Тогда
		Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
	КонецЕсли;

	Запрос.УстановитьПараметр("КонецПериода",  НачалоДня(КонецПериода));
	Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(НачалоПериода));
	Запрос.УстановитьПараметр("Шаг",           Шаг);

	РезультатЗапроса = Запрос.Выполнить();

	Если ПолучитьРезультатЗапроса Тогда
		Возврат РезультатЗапроса;
	КонецЕсли;

	Если ПолучитьТаблицуЗначений Тогда
		Возврат РезультатЗапроса.Выгрузить();
	КонецЕсли;

КонецФункции
```