При работе с динамическими списками в 1С:Предприятии 8.3 программисты часто сталкиваются с ситуацией, когда параметр в запросе, заключенный в фигурные скобки {}, все равно требует заполнения при открытии формы. Это вызывает ошибку «Значение параметра не задано», что сбивает с толку, ведь синтаксис системы компоновки данных (СКД) подразумевает его необязательность. В этой статье мы подробно разберем, почему так происходит, и рассмотрим несколько эффективных способов решения данной проблемы.
Проанализируем ситуацию: использование фигурных скобок {ГДЕ Документ.Кабинет = &Кабинет} является частью расширения языка запросов для СКД. Теоретически, если параметр не задан, условие должно просто исключаться из итогового запроса к базе данных. Однако на практике система может блокировать выполнение запроса, если параметр объявлен в настройках динамического списка, но его значение не инициализировано и не помечено как неиспользуемое.
Выясним причину: платформа проверяет наличие значений для всех активных параметров. Если параметр «доступен» в настройках компоновки, но программист не передал в него значение и не отключил его использование, система выдает ошибку. Чтобы исправить это, нам нужно научиться управлять свойством Использование программно или изменить подход к проектированию самого запроса.
Это самый надежный и гибкий метод. Вместо того чтобы просто устанавливать значение, мы будем явно указывать системе, нужно ли вообще учитывать этот параметр в текущем сеансе работы со списком. Рассмотрим пример кода, который обычно размещается в процедуре ПриСозданииНаСервере или в обработчике изменения реквизитов отбора.
Разберем по шагам, как это реализовать:
Использование в зависимости от результата проверки.
// Пример управления параметром "Кабинет"
ЭлементПараметра = Список.Параметры.Элементы.Найти("Кабинет");
Если ЭлементПараметра <> Неопределено Тогда
ЭлементПараметра.Значение = КабинетОтбор;
// Если значение не заполнено, выключаем параметр, чтобы условие ГДЕ не применялось
ЭлементПараметра.Использование = ЗначениеЗаполнено(КабинетОтбор);
КонецЕсли;
Проанализируем ситуацию с комментарием, упомянутую в обсуждении. Если нам нужно вывести все записи, мы просто устанавливаем Использование = Ложь. Если только записи с конкретным комментарием — устанавливаем значение и Использование = Истина.
Существует более «изящный» способ работы с необязательными условиями в динамических списках, который позволяет избежать жесткой привязки к именованным параметрам &Параметр. Посмотрим на использование символа .* в расширении запроса.
Вместо написания конкретного условия с параметром:
{ГДЕ Документ.Кабинет = &Кабинет}
Мы можем прописать:
{ГДЕ Документ.Кабинет.* КАК Кабинет}
Что это дает? В этом случае поле Кабинет становится доступным в стандартных настройках отбора динамического списка. Система сама добавит нужное условие в SQL-запрос только тогда, когда пользователь или программист установит отбор по этому полю. Если отбор не установлен, запрос остается «чистым», и никакие ошибки о незаполненных параметрах не возникают.
Рассмотрим задачу, когда нужно переключаться между режимами «Показать всё» и «Показать только те, где заполнено поле (например, Комментарий)». Использование параметров здесь может быть избыточным. Проанализируем, как это сделать через элементы отбора динамического списка.
Для реализации логики «Только записи с комментарием» (где комментарий не пустой) используем следующий подход:
// Найдем или создадим элемент отбора
ПолеОтбора = Новый ПолеКомпоновкиДанных("Комментарий");
ЭлементОтбора = Неопределено;
// Ищем существующий отбор, чтобы не дублировать
Для Каждого Элемент Из Список.Отбор.Элементы Цикл
Если Элемент.ЛевоеЗначение = ПолеОтбора Тогда
ЭлементОтбора = Элемент;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЭлементОтбора = Неопределено Тогда
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = ПолеОтбора;
КонецЕсли;
// Устанавливаем режим: Показать только заполненные
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено;
ЭлементОтбора.Использование = ПоказатьТолькоСКомментарием; // Истина или Ложь
Важный момент: Если вы хотите вывести вообще все записи (и пустые, и заполненные), достаточно просто установить Использование = Ложь для данного элемента отбора. Система компоновки данных сама исключит это условие из финального текста запроса.
При настройке необязательных условий важно помнить о производительности СУБД. Посмотрим, как наши действия влияют на скорость работы:
{ГДЕ...} является предпочтительным. Когда условие отключено через Использование = Ложь, оно полностью вырезается из текста запроса. СУБД получает лаконичный SQL-код, который легче оптимизировать.ГДЕ (Поле = &Параметр ИЛИ &ПараметрПустой). Это классическая ошибка, которая часто приводит к полному сканированию таблицы (Table Scan), так как оптимизатор запросов не может эффективно использовать индексы.Подведем итог: для корректной работы необязательных параметров в динамическом списке следует либо использовать программное управление свойством Использование в коллекции Список.Параметры, либо переходить на использование гибких отборов {ГДЕ Поле.*}. Это обеспечит стабильную работу интерфейса без лишних сообщений об ошибках и сохранит высокую скорость работы базы данных.