Как программно сформировать текст запроса для динамического списка в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с управляемыми формами в 1С:Предприятии 8.3 разработчики часто сталкиваются с необходимостью кастомизации данных, отображаемых в динамическом списке. Если стандартных настроек основной таблицы недостаточно и требуется добавить специфические соединения с другими таблицами (например, регистрами сведений или дополнительными справочниками), встает вопрос: как сделать это грамотно, не превращая код в «заплатку»?

Рассмотрим, как реализовать формирование запроса программно с использованием объекта СхемаЗапроса, что позволяет гибко управлять структурой данных и поддерживать код в актуальном состоянии при изменениях метаданных.

Понимание механизма автоматической генерации

Когда свойство динамического списка ПроизвольныйЗапрос установлено в значение Ложь, платформа 1С автоматически генерирует SQL-запрос к СУБД. Этот механизм анализирует метаданные основной таблицы и автоматически включает в выборку:

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

Реализация через СхемаЗапроса

Если вам необходимо добавить в список данные из других таблиц, вы можете перевести список в режим ПроизвольныйЗапрос = Истина и программно сформировать текст запроса. Использование СхемаЗапроса является более современным и удобным подходом, чем простое конкатенирование строк запроса.

Разберем по шагам, как собрать такой запрос:

  1. Создаем объект СхемаЗапроса.
  2. Добавляем пакет запросов и получаем первый оператор.
  3. Добавляем источники данных (основную таблицу и таблицы для соединения).
  4. Настраиваем условия соединения.
  5. Программно перебираем метаданные основной таблицы, чтобы включить нужные поля в выборку.
  6. Добавляем специфические поля из других источников.

Рассмотрим пример реализации для документа ЗаказКлиента с присоединением данных из регистра сведений:


СхемаЗапроса = Новый СхемаЗапроса;
ЗапросСписка = СхемаЗапроса.ПакетЗапросов.Добавить();
ОператорЗаказов = ЗапросСписка.Операторы[0];

// Добавляем основные источники
ИсточникЗаказы = ОператорЗаказов.Источники.Добавить("Документ.ЗаказКлиента", "ЗаказКлиента");
ИсточникАдресаДоставки = ОператорЗаказов.Источники.Добавить("РегистрСведений.Адр1_АдресаДокументов", "АдресаДокументов");

// Настраиваем соединение
СоединениеАдресаДоставки = ИсточникАдресаДоставки.Соединения[0];
СоединениеАдресаДоставки.ТипСоединения = ТипСоединенияСхемыЗапроса.ПравоеВнешнее;
СоединениеАдресаДоставки.Условие = Новый ВыражениеСхемыЗапроса("ЗаказКлиента.Ссылка = АдресаДокументов.Документ");

// Добавляем стандартные поля
ОператорЗаказов.ВыбираемыеПоля.Добавить("ЗаказКлиента.Ссылка");
ОператорЗаказов.ВыбираемыеПоля.Добавить("ЗаказКлиента.Номер");
ОператорЗаказов.ВыбираемыеПоля.Добавить("ЗаказКлиента.Дата");
ОператорЗаказов.ВыбираемыеПоля.Добавить("ЗаказКлиента.ПометкаУдаления");
ОператорЗаказов.ВыбираемыеПоля.Добавить("ЗаказКлиента.Проведен");
ОператорЗаказов.ВыбираемыеПоля.Добавить("ЗаказКлиента.МоментВремени");

// Автоматический перебор реквизитов документа
РеквизитыЗаказа = Метаданные.Документы.ЗаказКлиента.Реквизиты;
Для Каждого РеквизитЗаказа Из РеквизитыЗаказа Цикл
    ОператорЗаказов.ВыбираемыеПоля.Добавить("ЗаказКлиента." + РеквизитЗаказа.Имя);
КонецЦикла;

// Добавление специфических полей с псевдонимами
ОператорЗаказов.ВыбираемыеПоля.Добавить("ЗаказКлиента.Партнер.ГруппаДоступа");
КоличествоКолонок = ЗапросСписка.Колонки.Количество();
ЗапросСписка.Колонки[КоличествоКолонок].Псевдоним = "Адр1_ГруппаДоступа";

ОператорЗаказов.ВыбираемыеПоля.Добавить("ЕСТЬNULL(АдресаДокументов.АдресДоставки, ЗНАЧЕНИЕ(Справочник.Адр1_АдресаДоставки.ПустаяСсылка))");
ЗапросСписка.Колонки[КоличествоКолонок + 1].Псевдоним = "Адр1_АдресДоставки";

// Применяем запрос к динамическому списку
Список.ПроизвольныйЗапрос = Истина;
Список.ТекстЗапроса = СхемаЗапроса.ПолучитьТекстЗапроса();

Рекомендации и предостережения

При использовании данного подхода важно учитывать следующие аспекты:

Используя предложенный алгоритм, вы обеспечите гибкость и «чистоту» реализации динамических списков, сохраняя при этом контроль над тем, какие данные попадают в интерфейс пользователя.

← На главную