Как в 1С использовать запрос для выбора элементов в Список значений на управляемой форме

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

При разработке на управляемых формах 1С 8.3 программисты часто сталкиваются с ситуацией, когда стандартных возможностей выбора элементов в СписокЗначений недостаточно. Возникает соблазн использовать объект ДинамическийСписок внутри списка значений, надеясь, что платформа сама сформирует выборку на основе произвольного запроса. Однако здесь кроется фундаментальная архитектурная ловушка.

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

Разберем концептуальное различие объектов

Для начала проанализируем, чем отличаются эти объекты, так как путаница в терминах — основная причина затруднений. Проанализируем их назначение:

  1. Список значений (ValueList) — это универсальная коллекция значений, которая используется для хранения небольшого набора элементов (ссылок, строк, чисел). На форме он отображается как список с кнопками "Добавить", "Удалить", "Подбор". Это хранилище данных.
  2. Динамический список (DynamicList) — это специальный программный объект, предназначенный исключительно для отображения данных из таблиц базы данных в элементе формы типа "Таблица". Он умеет эффективно подгружать данные порциями, выполнять сортировку и группировку на уровне SQL-запроса. Это инструмент отображения.

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

Почему настройка Произвольный запрос недоступна для списка значений

Рассмотрим ситуацию: вы создали реквизит формы со свойством "Список значений", установили тип элементов как "Динамический список", но не видите привычной кнопки "Настройка списка" с полем для текста запроса. Это происходит потому, что СписокЗначений — это не база данных. Он не умеет выполнять запросы самостоятельно. Его задача — просто хранить то, что в него положили.

Настройка Произвольный запрос появляется только тогда, когда сам основной реквизит имеет тип ДинамическийСписок. Если же ваша задача — сделать так, чтобы пользователь при нажатии кнопки "Добавить" выбирал элементы из списка, сформированного по сложному алгоритму, нужно использовать другие механизмы.

Способ 1. Использование стандартной формы выбора с отборами

Это самый простой и правильный с точки зрения архитектуры 1С способ. Если вам нужно ограничить выбор элементов в списке значений (например, показывать только товары определенной группы), мы можем использовать Параметры выбора или Связи параметров выбора.

Посмотрим, как это настроить в конфигураторе:

  1. Выделите реквизит формы типа СписокЗначений.
  2. В свойстве Тип значения укажите конкретный тип ссылки, например, СправочникСсылка.Номенклатура.
  3. Найдите свойство Параметры выбора. Здесь вы можете добавить фиксированные отборы, которые будут переданы в форму выбора.

Если же логика отбора слишком сложная для фиксированных параметров, мы можем указать конкретную Форму выбора, в которой уже будет настроен ДинамическийСписок с нужным вам произвольным запросом. В этом случае платформа сама откроет нужную форму, а после выбора вернет результат в ваш список.

Способ 2. Программный подбор через событие НачалоВыбора

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

Для этого выполним следующие шаги:

  1. Для элемента формы (поля ввода), связанного со списком значений, создадим обработчик события НачалоВыбора.
  2. В коде обработчика установим СтандартнаяОбработка = Ложь.
  3. Программно откроем форму выбора с передачей необходимых параметров.

Пример программной реализации:


&НаКлиенте
Процедура МойСписокЗначенийНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    // Отменяем стандартное открытие формы выбора
    СтандартнаяОбработка = Ложь;
    
    // Подготовим параметры для формы выбора
    ПараметрыВыбора = Новый Структура;
    ПараметрыВыбора.Вставить("МножественныйВыбор", Истина);
    ПараметрыВыбора.Вставить("ЗакрыватьПриВыборе", Истина);
    
    // Если нужно передать специфический отбор для динамического списка формы выбора
    Отбор = Новый Структура("Услуга", Истина);
    ПараметрыВыбора.Вставить("Отбор", Отбор);
    
    // Открываем форму выбора справочника. 
    // Элемент - это владелец формы, в который вернется значение.
    ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыВыбора, Элемент);
    
КонецПроцедуры

Способ 3. Прямое заполнение списка значений результатом запроса

Выясним причину, по которой иногда требуется именно СписокЗначений: часто это нужно для автоматического заполнения какими-то данными без участия пользователя. Если вы хотите, чтобы при открытии формы или нажатии кнопки список заполнился данными из базы по запросу, ДинамическийСписок как реквизит вам вообще не нужен.

Разберем, как это сделать правильно через объект Запрос на стороне сервера:


&НаСервере
Процедура ЗаполнитьСписокПоЗапросуНаСервере()
    
    // Очищаем текущий список
    Объект.МойСписокЗначений.Очистить();
    
    // Создаем обычный запрос к базе данных
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Номенклатура.Ссылка КАК Ссылка
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |	Номенклатура.ПометкаУдаления = ЛОЖЬ
        |	И Номенклатура.ВидНоменклатуры = &ВидНоменклатуры";
    
    Запрос.УстановитьПараметр("ВидНоменклатуры", Справочники.ВидыНоменклатуры.Товар);
    
    РезультатЗапроса = Запрос.Выполнить();
    
    // Выгружаем результат в таблицу значений
    ТаблицаДанных = РезультатЗапроса.Выгрузить();
    
    // Загружаем колонку со ссылками прямо в список значений
    Объект.МойСписокЗначений.ЗагрузитьЗначения(ТаблицаДанных.ВыгрузитьКолонку("Ссылка"));
    
КонецПроцедуры

Этот метод является наиболее производительным, если данные не нужно редактировать интерактивно через форму выбора, а требуется просто получить срез данных из базы.

Особенности работы с типом ДинамическийСписок в программном коде

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


// Это создание программного объекта, не связанного с формой
ДС = Новый ДинамическийСписок;
ДС.ПроизвольныйЗапрос = Истина;
ДС.ТекстЗапроса = "ВЫБРАТЬ * ИЗ Справочник.Склады";
ДС.ОсновнаяТаблица = "Справочник.Склады";

// Чтобы получить данные из него, вам все равно придется использовать компоновщик макета 
// или выводить его в таблицу формы. В СписокЗначений он сам не "перетечет".

Проанализировав ситуацию, мы видим, что ДинамическийСписок — это мощный инструмент для построения интерфейса таблиц, в то время как СписокЗначений — это контейнер данных. Платформа 1С позволяет выбрать один тип в качестве другого только из-за универсальности системы типов, но практического применения такая связка не имеет.

Резюмируем: если вам нужен запрос — используйте объект Запрос для программного заполнения или полноценный реквизит ДинамическийСписок для вывода в таблицу формы. Если вам нужен выбор из списка — настраивайте Форму выбора и Параметры выбора для вашего СпискаЗначений.

← На главную