Как обойти ограничения функциональных опций в динамическом списке?

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

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

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

Суть проблемы: почему стандартные механизмы не помогают

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

Рассмотрим несколько эффективных способов «маскировки» реквизита от механизма проверки функциональных опций.

Способ 1. Использование логических выражений в тексте запроса

Проанализируем самый простой и действенный метод. Вместо прямого обращения к полю Справочник1.Реквизит2, мы можем обернуть его в конструкцию ВЫБОР. Платформа воспринимает такое поле не как прямой реквизит, а как результат выражения, и механизм ФО перестает на него влиять.

Рассмотрим пример реализации через программную подмену текста запроса при создании формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Определяем поля, которые скрыты из-за ФО
    ОтключенныеПоля = Новый Массив;
    ДоступныеПоляВыбора = Список.КомпоновщикНастроек.Настройки.ДоступныеПоляВыбора.Элементы;
    
    Для Каждого Поле Из Список.Поля Цикл
        НайденноеПоле = ДоступныеПоляВыбора.Найти(Поле.Поле);
        Если НайденноеПоле = Неопределено Тогда
            // Если поле описано в списке, но его нет в доступных — оно отключено ФО
            ОтключенныеПоля.Добавить(Поле);
        КонецЕсли;
    КонецЦикла;
    
    // Модифицируем текст запроса
    ТекстЗапроса = Список.ТекстЗапроса;
    ИмяТаблицы = "СправочникСправочник1"; // Имя таблицы в запросе
    
    Для Каждого ОтключенноеПоле Из ОтключенныеПоля Цикл
        ИмяПоля = ОтключенноеПоле.Поле;
        СтарыйТекст = ИмяТаблицы + "." + ИмяПоля;
        
        // Маскируем обращение к полю
        НовыйТекст = "ВЫБОР КОГДА ИСТИНА ТОГДА " + СтарыйТекст + " ИНАЧЕ NULL КОНЕЦ";
        ТекстЗапроса = СтрЗаменить(ТекстЗапроса, СтарыйТекст, НовыйТекст + " КАК " + ИмяПоля);
    КонецЦикла;
    
    Список.ТекстЗапроса = ТекстЗапроса;
    
КонецПроцедуры

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

Способ 2. Использование вложенных запросов

Еще один надежный способ — спрятать реквизит внутри вложенного запроса. Платформа анализирует связи ФО преимущественно на верхнем уровне запроса динамического списка. Если мы выберем данные во вложенном запросе и переименуем их, связь с функциональной опцией часто разрывается.

Разберем структуру такого запроса:


ВЫБРАТЬ
    Вложенный.Ссылка,
    Вложенный.Реквизит2_Скрытый КАК Реквизит2
ИЗ
    (ВЫБРАТЬ
        Спр.Ссылка КАК Ссылка,
        Спр.Реквизит2 КАК Реквизит2_Скрытый
    ИЗ
        Справочник.Справочник1 КАК Спр) КАК Вложенный

При таком подходе поле Реквизит2 на верхнем уровне будет доступно в компоновщике настроек даже при выключенной опции.

Способ 3. Принудительное приведение типов (ВЫРАЗИТЬ)

Выясним причину, почему простая конструкция ВЫБОР иногда может не срабатывать. Платформа постоянно совершенствуется, и оптимизатор запросов может «схлопывать» очевидные выражения. Чтобы этого избежать, добавим оператор ВЫРАЗИТЬ. Это создает жесткую инструкцию для парсера метаданных.

Пример выражения в тексте запроса ДС:

ВЫРАЗИТЬ(ВЫБОР КОГДА ИСТИНА ТОГДА Таблица.Реквизит2 ИНАЧЕ NULL КОНЕЦ КАК Число(10, 2))

Использование ВЫРАЗИТЬ разрывает прямую метаданную связь в глазах парсера динамического списка, делая поле доступным для отборов.

Способ 4. Создание «теневых» реквизитов через расширение

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

  1. Добавляем в расширение новый реквизит (например, имя_Реквизит2_Дубль).
  2. Этот реквизит не включаем в состав функциональных опций.
  3. В модуле объекта (в расширении) в событии ПередЗаписью прописываем копирование значения из основного реквизита в «дублирующий».
  4. В динамическом списке используем именно этот новый реквизит.

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

Важные нюансы и ограничения

При использовании методов обхода ФО следует учитывать несколько технических аспектов:

Таким образом, наиболее универсальным программным решением является маскировка поля через выражение ВЫБОР в тексте запроса динамического списка. Это позволяет сохранить функциональность интерфейса и доступ к данным даже при строгих ограничениях функциональных опций.

← На главную