Обновление конфигурации 1С:Бухгалтерия предприятия 3.0 и переход на новые релизы платформы 8.3.18 или 8.3.20 часто сопровождается неожиданными изменениями в поведении привычных механизмов. Одной из таких проблем является внезапный отказ программно установленных отборов в расширениях, который сопровождается ошибкой: "Параметры Отбора, Сортировки, Группировки или список отображаемых полей заданы неверно. Не найдено поле отбора Ответственный". Рассмотрим детально, почему это происходит и как правильно адаптировать код расширения под новые требования системы. На этапе планирования миграции полезно изучить раздел с готовыми решениями для переноса данных в 1С:Бухгалтерию.
Разберем программный код, который успешно работал долгое время, но перестал функционировать после обновления конфигурации до релиза 3.0.107.37 и платформы до 8.3.18.1741. Типовой сценарий использования расширения предполагает установку фильтра по текущему пользователю в процедуре ПриСозданииНаСервере:
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
Если не РольДоступна("ПолныеПрава") Тогда
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(Список.Отбор, "Ответственный", ПользователиКлиентСервер.ТекущийПользователь());
ЗапрещенныеВОтбореПоля = Новый Массив;
ЗапрещенныеВОтбореПоля.Добавить("Ответственный");
ЗапрещенныеВОтбореПоля.Добавить("Ссылка");
Список.УстановитьОграниченияИспользованияВОтборе(ЗапрещенныеВОтбореПоля);
КонецЕсли;
КонецПроцедуры
Проанализируем этот алгоритм. Сначала вызывается метод общего модуля для установки значения отбора по полю Ответственный. Затем создается массив полей, которые система должна скрыть из настроек формы, чтобы пользователь не мог самостоятельно изменить или удалить установленный фильтр. Наконец, вызывается метод динамического списка УстановитьОграниченияИспользованияВОтборе. Именно в этой цепочке действий после обновления возникает конфликт.
Основная причина кроется в изменении работы механизма компоновки данных (СКД), который лежит в основе динамических списков, и в повышении режима совместимости конфигурации. Рассмотрим несколько ключевых факторов:
Ответственный не выведено на форму как колонка или в его свойствах в конфигураторе не установлена галочка "Использовать всегда", платформа может исключить его из выборки в целях повышения производительности.УстановитьОграниченияИспользованияВОтборе на платформе 8.3.18 начал работать более жестко. Если поле добавляется в массив запрещенных, система может полностью исключить его из контекста доступных полей динамического списка еще до того, как отработает фактическая установка значения отбора. Это и приводит к ошибке "Не найдено поле отбора".Как показала практика, самым простым и быстрым способом восстановить работоспособность является исключение вызова метода УстановитьОграниченияИспользованияВОтборе. Проанализируем, как изменится поведение системы. При использовании функции ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора отбор все равно будет установлен, но поле не будет заблокировано для пользователя "намертво" на уровне структуры списка.
Рассмотрим измененный код:
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
Если не РольДоступна("ПолныеПрава") Тогда
// Устанавливаем отбор стандартным средством БСП
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(Список.Отбор, "Ответственный", ПользователиКлиентСервер.ТекущийПользователь());
// Закомментируем или удалим блок, вызывающий ошибку
// ЗапрещенныеВОтбореПоля = Новый Массив;
// ЗапрещенныеВОтбореПоля.Добавить("Ответственный");
// Список.УстановитьОграниченияИспользованияВОтборе(ЗапрещенныеВОтбореПоля);
КонецЕсли;
КонецПроцедуры
В большинстве случаев этого достаточно, чтобы ошибка исчезла, а фильтрация документов по ответственному лицу заработала корректно.
Если бизнес-логика требует, чтобы пользователь гарантированно не мог видеть или менять этот отбор в окне "Настроить список", рекомендуется использовать управление свойством РежимОтображения конкретного элемента отбора. Этот способ гораздо стабильнее, чем блокировка целого поля через УстановитьОграниченияИспользованияВОтборе.
Разберем по шагам, как реализовать этот метод:
Недоступный или Невидимый.Посмотрим на пример реализации:
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
Если не РольДоступна("ПолныеПрава") Тогда
ТекущийПользователь = Пользователи.АвторизованныйПользователь();
// Используем встроенные механизмы БСП для получения элемента
ЭлементОтбора = ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(
Список.Отбор,
"Ответственный",
ТекущийПользователь,
ВидСравненияКомпоновкиДанных.Равно,
"По ответственному",
Истина
);
// Блокируем изменение этого отбора пользователем в интерфейсе
Если ЭлементОтбора <> Неопределено Тогда
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Этот подход не удаляет поле из метаданных динамического списка, поэтому платформа не выдает ошибку о его отсутствии. При этом пользователь видит, что отбор применен, но не может его отредактировать. Для практического изучения возможностей компоновки данных пригодится демо-обработка для работы с отборами СКД на управляемых формах.
Если даже после упрощения кода ошибка "Не найдено поле" сохраняется, необходимо проверить настройки самого динамического списка в основной конфигурации или через расширение. Проанализируем свойства Реквизита формы с типом ДинамическийСписок.
Найдите в списке полей Ответственный. В окне свойств обратите внимание на флаг "Использовать всегда". Если он выключен, то при программном обращении к полю, которое физически не отображается на экране в данный момент, система может выдать ошибку. Включение этого флага гарантирует, что поле Ответственный всегда будет присутствовать в SQL-запросе, который платформа отправляет к базе данных, и будет доступно для манипуляций в коде.
Многие разработчики отмечают нестабильность релизов ветки 8.3.18 при работе с расширениями и динамическими списками в серверном режиме. Если вышеуказанные методы не помогают, стоит рассмотреть следующие технические шаги:
rphost с очисткой временных файлов сервера.Ответственный получается через соединение или имеет псевдоним (например, ВЫБРАТЬ Документ.Ответственный КАК Менеджер...), то в коде отбора нужно обращаться именно по псевдониму Менеджер.Подводя итог, можно сказать, что проблема "исчезновения" поля Ответственный чаще всего вызвана избыточным использованием метода УстановитьОграниченияИспользованияВОтборе, который в новых версиях платформы конфликтует с оптимизацией динамических списков. Переход на использование свойства РежимОтображения является наиболее правильным и современным решением этой задачи.