Почему перестал работать программный отбор в списках 1С:Бухгалтерия 3.0 после обновления?

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

Обновление конфигурации 1С:Бухгалтерия предприятия 3.0 и переход на новые релизы платформы 8.3.18 или 8.3.20 часто сопровождается неожиданными изменениями в поведении привычных механизмов. Одной из таких проблем является внезапный отказ программно установленных отборов в расширениях, который сопровождается ошибкой: "Параметры Отбора, Сортировки, Группировки или список отображаемых полей заданы неверно. Не найдено поле отбора Ответственный". Рассмотрим детально, почему это происходит и как правильно адаптировать код расширения под новые требования системы. На этапе планирования миграции полезно изучить раздел с готовыми решениями для переноса данных в 1С:Бухгалтерию.

Анализ исходной ситуации

Разберем программный код, который успешно работал долгое время, но перестал функционировать после обновления конфигурации до релиза 3.0.107.37 и платформы до 8.3.18.1741. Типовой сценарий использования расширения предполагает установку фильтра по текущему пользователю в процедуре ПриСозданииНаСервере:


&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    
    Если не РольДоступна("ПолныеПрава") Тогда
        ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(Список.Отбор, "Ответственный", ПользователиКлиентСервер.ТекущийПользователь());
        
        ЗапрещенныеВОтбореПоля = Новый Массив;
        ЗапрещенныеВОтбореПоля.Добавить("Ответственный");
        ЗапрещенныеВОтбореПоля.Добавить("Ссылка");
        Список.УстановитьОграниченияИспользованияВОтборе(ЗапрещенныеВОтбореПоля);
    КонецЕсли;

КонецПроцедуры

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

Выясняем причины возникновения ошибки

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

  1. Изменение состава доступных полей. В новых версиях БП 3.0 разработчики типовых решений часто оптимизируют запросы динамических списков. Если поле Ответственный не выведено на форму как колонка или в его свойствах в конфигураторе не установлена галочка "Использовать всегда", платформа может исключить его из выборки в целях повышения производительности.
  2. Конфликт метода ограничений. Метод УстановитьОграниченияИспользованияВОтборе на платформе 8.3.18 начал работать более жестко. Если поле добавляется в массив запрещенных, система может полностью исключить его из контекста доступных полей динамического списка еще до того, как отработает фактическая установка значения отбора. Это и приводит к ошибке "Не найдено поле отбора".
  3. Режим совместимости. При обновлении на релиз 3.0.107 и выше режим совместимости конфигурации обычно поднимается до 8.3.16 или выше. Это меняет логику работы расширений с объектами метаданных основной конфигурации.

Вариант решения №1: Отказ от метода жестких ограничений

Как показала практика, самым простым и быстрым способом восстановить работоспособность является исключение вызова метода УстановитьОграниченияИспользованияВОтборе. Проанализируем, как изменится поведение системы. При использовании функции ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора отбор все равно будет установлен, но поле не будет заблокировано для пользователя "намертво" на уровне структуры списка.

Рассмотрим измененный код:


&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    
    Если не РольДоступна("ПолныеПрава") Тогда
        // Устанавливаем отбор стандартным средством БСП
        ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(Список.Отбор, "Ответственный", ПользователиКлиентСервер.ТекущийПользователь());
        
        // Закомментируем или удалим блок, вызывающий ошибку
        // ЗапрещенныеВОтбореПоля = Новый Массив;
        // ЗапрещенныеВОтбореПоля.Добавить("Ответственный");
        // Список.УстановитьОграниченияИспользованияВОтборе(ЗапрещенныеВОтбореПоля);
    КонецЕсли;

КонецПроцедуры

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

Вариант решения №2: Современный способ скрытия отбора

Если бизнес-логика требует, чтобы пользователь гарантированно не мог видеть или менять этот отбор в окне "Настроить список", рекомендуется использовать управление свойством РежимОтображения конкретного элемента отбора. Этот способ гораздо стабильнее, чем блокировка целого поля через УстановитьОграниченияИспользованияВОтборе.

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

  1. Программно находим или создаем элемент отбора.
  2. Устанавливаем ему нужное значение и вид сравнения.
  3. Меняем режим отображения на Недоступный или Невидимый.

Посмотрим на пример реализации:


&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    
    Если не РольДоступна("ПолныеПрава") Тогда
        
        ТекущийПользователь = Пользователи.АвторизованныйПользователь();
        
        // Используем встроенные механизмы БСП для получения элемента
        ЭлементОтбора = ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(
            Список.Отбор, 
            "Ответственный", 
            ТекущийПользователь, 
            ВидСравненияКомпоновкиДанных.Равно, 
            "По ответственному", 
            Истина
        );
        
        // Блокируем изменение этого отбора пользователем в интерфейсе
        Если ЭлементОтбора <> Неопределено Тогда
            ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
        КонецЕсли;
        
    КонецЕсли;

КонецПроцедуры

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

Вариант решения №3: Проверка доступности поля в конфигураторе

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

Найдите в списке полей Ответственный. В окне свойств обратите внимание на флаг "Использовать всегда". Если он выключен, то при программном обращении к полю, которое физически не отображается на экране в данный момент, система может выдать ошибку. Включение этого флага гарантирует, что поле Ответственный всегда будет присутствовать в SQL-запросе, который платформа отправляет к базе данных, и будет доступно для манипуляций в коде.

Рекомендации по работе с платформой 8.3.18

Многие разработчики отмечают нестабильность релизов ветки 8.3.18 при работе с расширениями и динамическими списками в серверном режиме. Если вышеуказанные методы не помогают, стоит рассмотреть следующие технические шаги:

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

← На главную