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

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

При работе с динамическими списками в 1С:Предприятии 8.3 программисты часто сталкиваются с ситуацией, когда параметр в запросе, заключенный в фигурные скобки {}, все равно требует заполнения при открытии формы. Это вызывает ошибку «Значение параметра не задано», что сбивает с толку, ведь синтаксис системы компоновки данных (СКД) подразумевает его необязательность. В этой статье мы подробно разберем, почему так происходит, и рассмотрим несколько эффективных способов решения данной проблемы.

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

Проанализируем ситуацию: использование фигурных скобок {ГДЕ Документ.Кабинет = &Кабинет} является частью расширения языка запросов для СКД. Теоретически, если параметр не задан, условие должно просто исключаться из итогового запроса к базе данных. Однако на практике система может блокировать выполнение запроса, если параметр объявлен в настройках динамического списка, но его значение не инициализировано и не помечено как неиспользуемое.

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

Способ 1. Программное управление свойством «Использование»

Это самый надежный и гибкий метод. Вместо того чтобы просто устанавливать значение, мы будем явно указывать системе, нужно ли вообще учитывать этот параметр в текущем сеансе работы со списком. Рассмотрим пример кода, который обычно размещается в процедуре ПриСозданииНаСервере или в обработчике изменения реквизитов отбора.

Разберем по шагам, как это реализовать:

  1. Найдем нужный параметр в коллекции параметров динамического списка.
  2. Проверим, заполнено ли значение, по которому мы хотим фильтровать список.
  3. Установим свойство Использование в зависимости от результата проверки.

// Пример управления параметром "Кабинет"
ЭлементПараметра = Список.Параметры.Элементы.Найти("Кабинет");
Если ЭлементПараметра <> Неопределено Тогда
    ЭлементПараметра.Значение = КабинетОтбор;
    // Если значение не заполнено, выключаем параметр, чтобы условие ГДЕ не применялось
    ЭлементПараметра.Использование = ЗначениеЗаполнено(КабинетОтбор);
КонецЕсли;

Проанализируем ситуацию с комментарием, упомянутую в обсуждении. Если нам нужно вывести все записи, мы просто устанавливаем Использование = Ложь. Если только записи с конкретным комментарием — устанавливаем значение и Использование = Истина.

Способ 2. Использование расширения полей отбора (синтаксис со звездочкой)

Существует более «изящный» способ работы с необязательными условиями в динамических списках, который позволяет избежать жесткой привязки к именованным параметрам &Параметр. Посмотрим на использование символа .* в расширении запроса.

Вместо написания конкретного условия с параметром:

{ГДЕ Документ.Кабинет = &Кабинет}

Мы можем прописать:

{ГДЕ Документ.Кабинет.* КАК Кабинет}

Что это дает? В этом случае поле Кабинет становится доступным в стандартных настройках отбора динамического списка. Система сама добавит нужное условие в SQL-запрос только тогда, когда пользователь или программист установит отбор по этому полю. Если отбор не установлен, запрос остается «чистым», и никакие ошибки о незаполненных параметрах не возникают.

Способ 3. Реализация сложной логики (Все записи vs Только заполненные)

Рассмотрим задачу, когда нужно переключаться между режимами «Показать всё» и «Показать только те, где заполнено поле (например, Комментарий)». Использование параметров здесь может быть избыточным. Проанализируем, как это сделать через элементы отбора динамического списка.

Для реализации логики «Только записи с комментарием» (где комментарий не пустой) используем следующий подход:


// Найдем или создадим элемент отбора
ПолеОтбора = Новый ПолеКомпоновкиДанных("Комментарий");
ЭлементОтбора = Неопределено;

// Ищем существующий отбор, чтобы не дублировать
Для Каждого Элемент Из Список.Отбор.Элементы Цикл
    Если Элемент.ЛевоеЗначение = ПолеОтбора Тогда
        ЭлементОтбора = Элемент;
        Прервать;
    КонецЕсли;
КонецЦикла;

Если ЭлементОтбора = Неопределено Тогда
    ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = ПолеОтбора;
КонецЕсли;

// Устанавливаем режим: Показать только заполненные
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено;
ЭлементОтбора.Использование = ПоказатьТолькоСКомментарием; // Истина или Ложь

Важный момент: Если вы хотите вывести вообще все записи (и пустые, и заполненные), достаточно просто установить Использование = Ложь для данного элемента отбора. Система компоновки данных сама исключит это условие из финального текста запроса.

Рекомендации по производительности

При настройке необязательных условий важно помнить о производительности СУБД. Посмотрим, как наши действия влияют на скорость работы:

Подведем итог: для корректной работы необязательных параметров в динамическом списке следует либо использовать программное управление свойством Использование в коллекции Список.Параметры, либо переходить на использование гибких отборов {ГДЕ Поле.*}. Это обеспечит стабильную работу интерфейса без лишних сообщений об ошибках и сохранит высокую скорость работы базы данных.

← На главную