Календарь в запросе

23.02.15

Разработка - Запросы

Календарь в запросе (последовательный список дат за определенный период) без использования предварительно созданных объектов метаданных (таких как производственный календарь, график).

Предлагаю вам небольшой шаблон, который полезно иметь на руках, для решения различных задач связанных с датами и календарем в случаях, когда "производственный календарь" или "график" отсутствуют в конфигурации или когда использование их накладывает определенные ограничения (необходимость предварительного заполнения на определенный период).

 

За основу взят известный алгоритм получения чисел от 0 до 9999 в запросе, суть которого заключается в том, чтобы перемножить таблицы, содержащие цифры от 0 до 9, столько раз, сколько порядков вам требуется в итоговом максимальном числе. Например для получения последовательности цифр от 0 до 9999 - вам потребуется соединить 4 таблицы (как в примере).

Также добавлены дополнительные запросы, позволяющие определить название месяца, дня недели и является ли день стандартным выходным. Конечно, все это можно определить при выводе результата через СКД, но в данном случае это добавлено "на свякий случай", когда использование СКД не представляется возможным или целесообразным.

"ТаблицаМесяцев" - таблица, содержащая наименование месяцев.
"ТаблицаДнейНедели" - таблица, содержащая наименование дней недели и признак выходного дня.
"ТаблицаЦифр", "ТаблицаЧисел" - служебные таблицы, используемые для последующего построения таблицы "Календарь".
"Календарь" - таблица, содержащая непоследственно список дат за определенный период.
Результирующая таблица - фактически тот самый производственный каледнарь, за исключением праздников.

Сам запрос:

ВЫБРАТЬ
	"Январь" КАК НазваниеМесяца,
	1 КАК НомерМесяца
ПОМЕСТИТЬ ТаблицаМесяцев

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

ВЫБРАТЬ
	"Февраль",
	2

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

ВЫБРАТЬ
	"Март",
	3

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

ВЫБРАТЬ
	"Апрель",
	4

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

ВЫБРАТЬ
	"Май",
	5

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

ВЫБРАТЬ
	"Июнь",
	6

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

ВЫБРАТЬ
	"Июль",
	7

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

ВЫБРАТЬ
	"Август",
	8

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

ВЫБРАТЬ
	"Сентябрь",
	9

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

ВЫБРАТЬ
	"Октябрь",
	10

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

ВЫБРАТЬ
	"Ноябрь",
	11

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

ВЫБРАТЬ
	"Декабрь",
	12
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	"Понедельник" КАК ДеньНедели,
	"Пн" КАК ДеньНеделиСокращено,
	1 КАК НомерДняНедели,
	ЛОЖЬ КАК СтандартныйВыходной
ПОМЕСТИТЬ ТаблицаДнейНедели

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

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

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

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

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

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

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

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

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

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

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

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	0 КАК Цифра
ПОМЕСТИТЬ ТаблицаЦифр

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

ВЫБРАТЬ
	1

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

ВЫБРАТЬ
	2

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

ВЫБРАТЬ
	3

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

ВЫБРАТЬ
	4

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

ВЫБРАТЬ
	5

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

ВЫБРАТЬ
	6

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

ВЫБРАТЬ
	7

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

ВЫБРАТЬ
	8

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

ВЫБРАТЬ
	9
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ТаблицаЦифрДляТысяч.Цифра * 1000 + ТаблицаЦифрДляСотен.Цифра * 100 + ТаблицаЦифрДляДесятков.Цифра * 10 + ТаблицаЦифрДляЕдиниц.Цифра КАК Число
ПОМЕСТИТЬ ТаблицаЧисел
ИЗ
	ТаблицаЦифр КАК ТаблицаЦифрДляЕдиниц,
	ТаблицаЦифр КАК ТаблицаЦифрДляДесятков,
	ТаблицаЦифр КАК ТаблицаЦифрДляСотен,
	ТаблицаЦифр КАК ТаблицаЦифрДляТысяч
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ДОБАВИТЬКДАТЕ(&НачПериода, ДЕНЬ, ТаблицаЧисел.Число) КАК Дата
ПОМЕСТИТЬ Календарь
ИЗ
	ТаблицаЧисел КАК ТаблицаЧисел
ГДЕ
	ДОБАВИТЬКДАТЕ(&НачПериода, ДЕНЬ, ТаблицаЧисел.Число) <= &КонПериода
;

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

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


Календарь в запросе на каждую дату в запросе календарь даты в запросе производственный календарь график

См. также

SALE! 15%

Инструментарий разработчика Роли и права Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    159615    874    399    

862

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    9919    sergey279    18    

64

Запросы Программист Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    5195    XilDen    36    

80

Запросы Программист Запросы Бесплатно (free)

Отлаживая взаимодействие с базой данных, мы регулярно сталкиваемся с зависающими или подозрительно долго выполняющимися обращениями, негативно влияющими на производительность. О том, как в PostgreSQL выявить подозрительные запросы, основываясь на доступной о них информации, расскажем в статье.

16.08.2024    7929    user1840182    5    

28

Математика и алгоритмы Запросы Программист Платформа 1С v8.3 Запросы Бесплатно (free)

Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.

08.07.2024    2401    ivanov660    9    

22

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    8712    implecs_team    6    

47

Запросы Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Часто поступают задачи по произвольному распределению общих сумм. После распределения иногда пропадают копейки. Суть решения добавить АвтоНомерЗаписи() в ВТ распределения, и далее используя функции МАКСИМУМ или МИНИМУМ можем положить разницу копеек в первую или последнюю строку знаменателя распределения.

11.04.2024    3392    andrey_sag    10    

36
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. jobkostya1c_ERP 100 24.02.15 07:35 Сейчас в теме
Интересный прием. Похож на недавно попавшийся в отчете прием получения списка дат с &НачалоПериода по &КонецПериода
ВЫБРАТЬ
	ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, t.n) КАК Дата
ПОМЕСТИТЬ ТаблицаДата
ИЗ
	(ВЫБРАТЬ
		6 * (t1.a - 1) + t2.b - 1 КАК n
	ИЗ
		(ВЫБРАТЬ
			1 КАК a
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			2
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			3
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			4
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			5
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			6) КАК t1
			ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
				1 КАК b
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				2
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				3
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				4
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				5
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				6) КАК t2
			ПО (ИСТИНА)) КАК t
ГДЕ
	ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, t.n) <= &КонецПериода
Показать

Фрагмент из отчета по прайсу.

Прикрепленные файлы:
3. spezc 792 24.02.15 07:49 Сейчас в теме
(1) kostyaomsk, интересный запрос. сходу и не сообразил как работает. попробую в консоли.
4. spezc 792 24.02.15 07:58 Сейчас в теме
(1) kostyaomsk, вложенный запрос "ВЫБРАТЬ 6 * (t1.a - 1) + t2.b - 1 КАК n" возвращает числа от 0 до 35. В чем профит? Как получить больший диапазон?
jobkostya1c_ERP; +1 Ответить
5. jobkostya1c_ERP 100 24.02.15 08:34 Сейчас в теме
(4) тоже большой плюс Вам что заметили. У меня был приведенный выше фрагмент из отчета "прайс", показывающий изменения цен прайса на заданную грубину. Месяца, видимо, достаточно. Более точно 36 дней максимум в моем случае. Еще в коде стоит для этого ограничение на две цифры переменной "количество дней для проверки изменений". Можно и увеличить если нужно количество, но это сильно увеличит нагрузку на сервер.
Используется же ограничитель ГДЕ
ГДЕ
    ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, t.n) <= &КонецПериода

Полагаю, сначала все равно вся таблица запроса генерируется средствами SQL? Если лезть глубоко такого накопать можно.
2. jobkostya1c_ERP 100 24.02.15 07:48 Сейчас в теме
В случае автора результат в консоле запросов аналогичен. Наверное, стоит применять, когда действительно нужны таблицы месяцев и дней недели.
"ТаблицаМесяцев" - таблица, содержащая наименование месяцев.
"ТаблицаДнейНедели" - таблица, содержащая наименование дней недели и признак выходного дня.

Естественно, задачи бывают разные и стоит собирать подобные решения чтоб не ломать голову, когда нужно что-то срочное. Да и в таблице "ТаблицаДнейНедели" можно ставить свой признак выходного дня или она также будет промежуточной при объединении с еще одной таблицей.
6. OLEG4120 165 24.02.15 10:04 Сейчас в теме
На старых платформах (8.1) почему-то упорядочивание не срабатывает
7. spezc 792 24.02.15 10:18 Сейчас в теме
(6) OLEG4120, "УПОРЯДОЧИТЬ ПО ДатаКалендаря"?
8. mzelensky 53 25.02.15 11:04 Сейчас в теме
Единожды потребовалась такая ерундовина. Огромное спасибо!!!
9. enot_tut 20 24.12.15 15:01 Сейчас в теме
10. spezc 792 24.12.15 15:11 Сейчас в теме
(9) enot_tut, исходник чего? если запроса - то он в самой статье.
11. vhavagyan 24.03.17 15:04 Сейчас в теме
а если так. календарь на тридцать лет.

ВЫБРАТЬ
	ДОБАВИТЬКДАТЕ(&НачДата, ДЕНЬ, Числа.Число) КАК ДатаДень
ИЗ
	(ВЫБРАТЬ
		Разряд0.Цифра + Разряд1.Цифра * 10 + Разряд2.Цифра * 100 + Разряд3.Цифра * 1000 КАК Число
	ИЗ
		(ВЫБРАТЬ
			0 КАК Цифра
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			1
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			2
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			3
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			4
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			5
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			6
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			7
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			8
		
		ОБЪЕДИНИТЬ
		
		ВЫБРАТЬ
			9) КАК Разряд0
			ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
				0 КАК Цифра
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				1
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				2
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				3
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				4
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				5
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				6
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				7
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				8
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				9) КАК Разряд1
			ПО (ИСТИНА)
			ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
				0 КАК Цифра
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				1
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				2
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				3
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				4
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				5
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				6
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				7
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				8
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				9) КАК Разряд2
			ПО (ИСТИНА)
			ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
				0 КАК Цифра
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				1
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				2
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				3
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				4
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				5
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				6
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				7
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				8
			
			ОБЪЕДИНИТЬ
			
			ВЫБРАТЬ
				9) КАК Разряд3
			ПО (ИСТИНА)) КАК Числа
ГДЕ
	ДОБАВИТЬКДАТЕ(&НачДата, ДЕНЬ, Числа.Число) <= &КонДата
УПОРЯДОЧИТЬ ПО
ДатаДень
Показать
RomanBor; sh_max; spezc; +3 Ответить
Оставьте свое сообщение