v8: Конструирование сложных запросов для 1С Ключевые слова: запрос,отчет
К сожалению, в 1С нет встроенной возможности для описания подзапросов в виде хранимых процедур и т.п.
Но это ограничение достаточно легко обойти.
Рассмотрим пример.
Допустим, нам нужно выполнить некоторый запрос с группировкой над другим запросом Т. Сам запрос Т может быть тоже достаточно сложным.
Можно не включать запрос Т в описание запроса, а просто описать его поля. Простые поля можно просто заменить нулями, а сложные поля привести к нужному типу через Выразить:
ВЫБРАТЬ
Т.ОП,
Т.Контрагент,
Т.ОП.Представление,
Т.Контрагент.Представление,
Т.ДоходныйРасходный КАК ДоходныйРасходный,
Т.СтатусДоговора КАК СтатусДоговора,
СУММА(Т.СуммаПлан) КАК СуммаПлан,
СУММА(Т.СуммаФакт) КАК СуммаФакт
ИЗ
(ВЫБРАТЬ
ВЫРАЗИТЬ(&X КАК Справочник.Подразделения) КАК ОП,
ВЫРАЗИТЬ(&X КАК Справочник.Контрагенты) КАК Контрагент,
ЛОЖЬ КАК ДоходныйРасходный,
0 КАК СуммаПлан,
0 КАК СуммаФакт,
"" КАК СтатусДоговора) КАК Т
СГРУППИРОВАТЬ ПО
Т.ОП,
Т.Контрагент,
Т.ОП.Представление,
Т.Контрагент.Представление,
Т.ДоходныйРасходный,
Т.СтатусДоговора
УПОРЯДОЧИТЬ ПО
ДоходныйРасходный
ИТОГИ
СУММА(СуммаПлан),
СУММА(СуммаФакт)
ПО
ОБЩИЕ
АВТОУПОРЯДОЧИВАНИЕ
Далее нам нужно только заменить описание запроса Т на текст запроса Т.
Если текст запроса над запросом Т хранится в переменной ТекстЗапроса, а текст запроса Т хранится в переменной ТекстЗапросаТ, то сделать это можно так:
ТекстЗапроса=обЗаменитьСтрокуМежду(ТекстЗапроса, "ИЗ", "КАК Т", "ИЗ ("+ТекстЗапросаТ+") КАК Т");
Функция обЗаменитьСтрокуМежду заменяет строку между маркерами:
Функция обЗаменитьСтрокуМежду(ИсхСтр, МаркерНачала, МаркерКонца, СтрЗамены, ОставлятьМаркеры=ложь, Середина="") Экспорт
Перем С;
С=ИсхСтр;
Поз1=Найти(С, МаркерНачала);
Если Поз1=0 Тогда
Возврат С;
КонецЕсли;
Начало=Лев(С, Поз1-1);
Хвост=Сред(С, Поз1+СтрДлина(МаркерНачала));
Поз2=Найти(Хвост, МаркерКонца);
Если Поз2=0 Тогда
Возврат С;
КонецЕсли;
Середина=Лев(Хвост, Поз2-1);
Конец=Сред(Хвост, Поз2+СтрДлина(МаркерКонца));
С=Начало+?(ОставлятьМаркеры, МаркерНачала, "")+СтрЗамены+?(ОставлятьМаркеры, МаркерКонца, "")+Конец;
Возврат С;
КонецФункции
Таким образом вы можете в конструкторе отлаживать как исходный запрос Т, так и запрос над запросом Т.
Если в запросе нужно указать составное поле разного типа, можно использовать подобный запрос (вместо справочника валюты можно использовать любой другой ссылочный тип, он нужен только для связи двух таблиц):
ВЫБРАТЬ
ВЫРАЗИТЬ(НЕОПРЕДЕЛЕНО КАК Справочник.Подразделения) КАК Подразделение,
ВЫРАЗИТЬ(НЕОПРЕДЕЛЕНО КАК Документ.Спецификация) КАК Спецификация,
ВЫРАЗИТЬ(НЕОПРЕДЕЛЕНО КАК Документ.Протокол) КАК Протокол,
Документы.Ссылка КАК Документ,
ИЗ
Справочник.Валюты КАК Валюты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
ВЫРАЗИТЬ(НЕОПРЕДЕЛЕНО КАК Документ.ЗаявкаНаЗакупку) КАК Ссылка
ОБЪЕДИНИТЬ
ВЫБРАТЬ
ВЫРАЗИТЬ(НЕОПРЕДЕЛЕНО КАК Документ.Протокол)) КАК Документы
ПО (ИСТИНА)
Родилось на основе обсуждения v8: Подход к написанию сложных запросов
TormozIT
Здесь http://infostart.ru/projects/1274 можно скачать подсистему, в состав которой входит продвинутая консоль запросов, поддерживающая временные таблицы, автоматически генерирующая запрос-имитатор, а теперь еще и позволяет каждый подзапрос отдельно отлаживать в режиме дерева запроса!
|