В дополнение к отличным статьям:
infostart.ru/1c/articles/1222743/
infostart.ru/1c/articles/1453473/
про использование объекта «СхемаЗапроса» для редактирования текстов запросов, хочу обратить внимание на один момент.
Я использую объект «СхемаЗапроса» для модификации запросов в типовых конфигурациях. Это, на мой взгляд, самый правильный способ. В типовых конфигурапциях, как правило, текст запроса формируется в зависимости нескольких условий и функциональных опций и может браться из разных мест в конфигурации. Также разработчики конфигурации используют сложные запросы с несколькими соединениями и если надо, допустим, добавить еще одно, то через функцию СтрЗаменить это сделать достаточно сложно.
Обычно для модификации запроса использую следующий код.
Например, надо в текст запроса надо добавить колонки из нового регистра.
СхемаЗапроса = Новый СхемаЗапроса;
СхемаЗапроса.УстановитьТекстЗапроса(ДинамическийСписок.ТекстЗапроса);
ЗапросСхемы = СхемаЗапроса.ПакетЗапросов[0];
ОператорВыбрать = ЗапросСхемы.Операторы[0];
ВыбираемыеПоля = ОператорВыбрать.ВыбираемыеПоля;
УсловияОтбора = ОператорВыбрать.Отбор;
ИсточникОтбора = ОператорВыбрать.Источники[0];
ПсевдонимОсновнойТаблицы = ИсточникОтбора.Источник.Псевдоним;
// добавление источников
ИсточникНовыйРегистр = ОператорВыбрать.Источники.Добавить("РегистрСведений.<Регистр_с_которым_соединяем_основную_таблицу>",
"<псевдоним_регистра_в_запросе>");
// по умолчанию, при добавлении источника объект СхемаЗапроса пытается сам установить связи,
// как правило, неудачно, поэтому очистим их и явно добавим связи
ИсточникНовыйРегистр.Соединения.Очистить();
// добавление связей
СоединениеНовыйРегистр = ИсточникОтбора.Соединения.Добавить(ИсточникНовыйРегистр,
СтрШаблон("<псевдоним_регистра_в_запросе>.<реквизит_для_связи_с_основной_таблицей> = %1.Ссылка", ПсевдонимОсновнойТаблицы));
// добавление колонок
КоличествоКолонок = ЗапросСхемы.Колонки.Количество();
ВыбираемыеПоля.Добавить("<псевдоним_регистра_в_запросе>.<добавляемая_колонка_1>");
ЗапросСхемы.Колонки[КоличествоКолонок].Псевдоним = "<псевдоним_добавляемой_колонки_1>";
КоличествоКолонок = КоличествоКолонок + 1;
ВыбираемыеПоля.Добавить("<псевдоним_регистра_в_запросе>.<добавляемая_колонка_2>");
ЗапросСхемы.Колонки[КоличествоКолонок].Псевдоним = "<псевдоним_добавляемой_колонки_2>";
КоличествоКолонок = КоличествоКолонок + 1;
ТекстЗапроса = СхемаЗапроса.ПолучитьТекстЗапроса();
ДинамическийСписок.ТекстЗапроса = ТекстЗапроса;
Все отлично работает, но если в запросе не присутствуют расширения языка запросов СКД. В этом случае так запрос отличается от сделанного «вручную». Пример взят из конфигурации 1С:Документооборот.
{ГДЕ
(ЗадачаИсполнителя.Выполнена = &Выполнена) КАК Поле2,
(ЗадачаИсполнителя.СрокИсполнения < &ДатаДляОтображенияПросроченных
И ЗадачаИсполнителя.СрокИсполнения > ДАТАВРЕМЯ(1, 1, 1)) КАК Поле4,
(ЗадачаИсполнителя.ПринятаКИсполнению = &ОтображатьСтарыеЗадачи) КАК Поле6,
(ЗадачаИсполнителя.Автор = &Автор) КАК Поле8,
(ЗадачаИсполнителя.Проект = &Проект) КАК Поле10}
В текст запроса добавляются автоматические созданные псевдонимы "Поле2", "Поле4" и т.д.
И такая вставка приводи к ошибке времени выполнения.
Видимо, расширение языка запроса СКД появилось позже чем объект «СхемаЗапроса». И авторы расширения запросов СКД старались сделать, чтобы это расширение было максимально совместимым с тем, что создано до этого. Но этот момент остался вне их внимания.
Для исправления ситуации я добавляю следующий код.
// нужно очистить псевдонимы выражений отбора компоновки данных, иначе генерится запрос
// с псевдонимами, который приводит к ошибке исполнения.
Для каждого ВыражениеОтбора Из ОператорВыбрать.ВыраженияОтбораКомпоновкиДанных Цикл
ВыражениеОтбора.Псевдоним = "";
КонецЦикла;
И итоге, получаем следующий код:
СхемаЗапроса = Новый СхемаЗапроса;
СхемаЗапроса.УстановитьТекстЗапроса(ДинамическийСписок.ТекстЗапроса);
ЗапросСхемы = СхемаЗапроса.ПакетЗапросов[0];
ОператорВыбрать = ЗапросСхемы.Операторы[0];
ВыбираемыеПоля = ОператорВыбрать.ВыбираемыеПоля;
УсловияОтбора = ОператорВыбрать.Отбор;
ИсточникОтбора = ОператорВыбрать.Источники[0];
ПсевдонимОсновнойТаблицы = ИсточникОтбора.Источник.Псевдоним;
// добавление источников
ИсточникНовыйРегистр = ОператорВыбрать.Источники.Добавить("РегистрСведений.<Регистр_с_которым_соединяем_основную_таблицу>",
"<псевдоним_регистра_в_запросе>");
// по умолчанию, при добавлении источника объект СхемаЗапроса пытается сам установить связи,
// как правило, неудачно, поэтому очистим их и явно добавим связи
ИсточникНовыйРегистр.Соединения.Очистить();
// добавление связей
СоединениеНовыйРегистр = ИсточникОтбора.Соединения.Добавить(ИсточникНовыйРегистр,
СтрШаблон("<псевдоним_регистра_в_запросе>.<реквизит_для_связи_с_основной_таблицей> = %1.Ссылка", ПсевдонимОсновнойТаблицы));
// добавление колонок
КоличествоКолонок = ЗапросСхемы.Колонки.Количество();
ВыбираемыеПоля.Добавить("<псевдоним_регистра_в_запросе>.<добавляемая_колонка_1>");
ЗапросСхемы.Колонки[КоличествоКолонок].Псевдоним = "<псевдоним_добавляемой_колонки_1>";
КоличествоКолонок = КоличествоКолонок + 1;
ВыбираемыеПоля.Добавить("<псевдоним_регистра_в_запросе>.<добавляемая_колонка_2>");
ЗапросСхемы.Колонки[КоличествоКолонок].Псевдоним = "<псевдоним_добавляемой_колонки_2>";
КоличествоКолонок = КоличествоКолонок + 1;
// нужно очистить псевдонимы выражений отбора компоновки данных, иначе генерится запрос
// с псевдонимами, который приводит к ошибке исполнения.
Для каждого ВыражениеОтбора Из ОператорВыбрать.ВыраженияОтбораКомпоновкиДанных Цикл
ВыражениеОтбора.Псевдоним = "";
КонецЦикла;
ТекстЗапроса = СхемаЗапроса.ПолучитьТекстЗапроса();
ДинамическийСписок.ТекстЗапроса = ТекстЗапроса;
В этом случае получаемый тест запрос идентичен такому же запросу, написанному вручную или через конструктор запроса.
Надеюсь, будет полезно. Спасибо за внимание!