Выпуск №12. Чудо-запросы 1С


Чудо-запросы 1С

На практике столкнулся с интересным отчетом и использовал его в своей конфигурации Транспортного Учета. Отчет красиво выводит по горизонтали информацию с данными из регистра сведений в соответствии с датами начала и окончания погрузки с определенного склада. Отчет без использования Схемы компоновки данных. Вот так он выглядит:

Что примечательного в нем, так это запрос, но прежде чем приводить код запроса вкратце опишу откуда собираются данные:

  • Во первых, это справочники портов отгрузки и складов
  • Во вторых это регистр сведений с Измерениями: "ДатаНачалаОтгрузки", "ДатаОкончанияОтгрузки", "Порт", "Склад" и Реквизитом "Заявка".

В запросе для каждого порта создаются временные таблицы с интервалами в полчаса от даты начала (выбранная дата + 6 часов, т.к. выгрузки с 6.30 утра до 16.30). В результате выполнения запроса получается такая таблица:

А вот и сама функция, возвращающая результат запроса:

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

Ну и сама процедура вывода отчета выглядит так:

Процедура СформироватьОтчетНаСервере() 
	
	ПолеТабличногоДокумента.Очистить();
	ПолеТабличногоДокумента.ОриентацияСтраницы 	= ОриентацияСтраницы.Ландшафт;
	ПолеТабличногоДокумента.ПолеСлева			= 0;
	ПолеТабличногоДокумента.ПолеСправа			= 0;
	ПолеТабличногоДокумента.АвтоМасштаб			= Истина;

	Макет = Отчеты.ГрафикДвиженияАвтотранспорта.ПолучитьМакет("Макет");
	ОбластьФормирование	= Макет.ПолучитьОбласть("ИнформацияОФормировании"); 
	ОбластьЗаголовок	= Макет.ПолучитьОбласть("ОбластьЗаголовок");
	ОбластьШапка 		= Макет.ПолучитьОбласть("ОбластьШапка");
	ОбластьСтрока		= Макет.ПолучитьОбласть("ОбластьСтрока|ОбластьСклад");
	ОбластьВремя		= Макет.ПолучитьОбласть("ОбластьСтрока|ОбластьВремя");
	ОбластьВремяЦвет	= Макет.ПолучитьОбласть("ОбластьСтрокаЦвет|ОбластьВремя");
	ОбластьОтгруженЦвет	= Макет.ПолучитьОбласть("ОбластьСтрокаЦветОтгружен|ОбластьВремя");
	ОбластьСтрокаСклад 	= Макет.ПолучитьОбласть("ОбластьСтрокаСклад");
	
	ОбластьФормирование.Параметры.ДатаФормирования = "Дата формирования: "+ТекущаяДата();
	ПолеТабличногоДокумента.Вывести(ОбластьФормирование);
	
	ОбластьЗаголовок.Параметры.Дата = Формат(Отчет.НаДату, "ДФ=dd.MM.yyyy");
	ПолеТабличногоДокумента.Вывести(ОбластьЗаголовок);
	ПолеТабличногоДокумента.Вывести(ОбластьШапка);
	ПолеТабличногоДокумента.ФиксацияСверху = 5;
	
	ВыборкаСклады = ПолучитьЗапрос().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
	
	Пока ВыборкаСклады.Следующий() Цикл
		ОбластьСтрокаСклад.Параметры.Склад = ВыборкаСклады.Склад;
		ПолеТабличногоДокумента.Вывести(ОбластьСтрокаСклад);
		
		ВыборкаПорты = ВыборкаСклады.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
		
		Пока ВыборкаПорты.Следующий() Цикл		
			ОбластьСтрока.Параметры.СкладПорт = ВыборкаПорты.Порт;
			ПолеТабличногоДокумента.Вывести(ОбластьСтрока);
			Выборка = ВыборкаПорты.Выбрать();
			ПредЗнач="";
			
			
			Пока Выборка.Следующий() Цикл
				ТекЗнач = Выборка.Заявка;
				Если ТекЗнач = NULL Тогда
					ТекОбласть = ОбластьВремя;
				Иначе
					ТекОбласть = ОбластьВремяЦвет;
				КонецЕсли;
				ТекОбласть.Параметры.Время = "";
				Если ПредЗнач <> ТекЗнач Тогда
					ТекстЗаявки = "";
					Если ЗначениеЗаполнено(Выборка.Заявка) Тогда
						ТЗ_Заявки = Выборка.Заявка.ЗаявкиКонтрагентов.Выгрузить();
						ТЗ_Заявки.Свернуть("Контрагент");
						Если Отчет.ПоказыватьМаршрут Тогда
							ТекстЗаявки = "; " + СокрЛП(Выборка.Заявка.МаршрутПеревозки) + "; ";
						Иначе
							ТекстЗаявки = "; ";
						КонецЕсли;
											
						Для Каждого СтрЗаявки Из ТЗ_Заявки Цикл
							Если ЗначениеЗаполнено(СтрЗаявки.Контрагент) Тогда 
								Если Отчет.ПоказыватьМаршрут Тогда
									ТекстЗаявки = ТекстЗаявки + ?(Прав(СокрЛП(ТекстЗаявки), 1) = ";", "", ", ") + СокрЛП(СтрЗаявки.Контрагент);
								Иначе
									ТекстЗаявки = ТекстЗаявки + ?(ТекстЗаявки = "; ", "", ", ") + СокрЛП(СтрЗаявки.Контрагент);
								КонецЕсли;	
																
							КонецЕсли;
						КонецЦикла;	
					КонецЕсли;
										
					ТекОбласть.Параметры.Время = ?(Выборка.МаркаТС="","",Выборка.МаркаТС+", "+Выборка.Автомобиль)+ТекстЗаявки;
					ТекОбласть.ТекущаяОбласть.Расшифровка = Выборка.Заявка;
				КонецЕсли;
				ПредЗнач = ТекЗнач;
				ПолеТабличногоДокумента.Присоединить(ТекОбласть);				
			КонецЦикла;		
		КонецЦикла;
	КонецЦикла;
	ПолеТабличногоДокумента.ФиксацияСлева = 2;
	ПолеТабличногоДокумента.Автомасштаб = Истина;
	
КонецПроцедуры


И последнее, что осталось показать, это макет:

На этом все, кому нужна конфигурация, регистрируйтесь, и просите ниже в комментариях я вышлю Вам нам почту.

 

Наверх


Добавить комментарий (через VK):

Добавить комментарий к статье могут только зарегистрированные пользователи: