При переходе на новые версии платформы 8.3 или при отключении режима совместимости с версией 8.2 многие разработчики и пользователи сталкиваются с неприятной ошибкой в динамических списках: «Невозможно применить фиксированные настройки. Пересекаются элементы отбора». Особенно часто это проявляется в сложных интерфейсах, таких как «Управление отгрузкой» в конфигурации «Управление торговлей 11.1» или других самописных обработках с динамическими списками.
Проанализируем ситуацию: почему старый код, который годами работал в режиме совместимости, внезапно начинает выдавать системные сообщения об ошибках? Разберем по шагам причины возникновения этой коллизии и рассмотрим эффективные методы ее устранения.
Начиная с версии 8.3, механизмы работы динамических списков стали значительно строже. Платформа теперь четко разделяет настройки списка на три независимых уровня, которые накладываются друг на друга последовательно:
Ошибка «пересечения» возникает в тот момент, когда одно и то же поле (например, Организация или Склад) одновременно присутствует в Фиксированных настройках и в Пользовательских настройках (или настройках СКД), причем платформа не может однозначно решить, какой из отборов должен доминировать. В режиме 8.2 платформа часто игнорировала такие дубли, но в 8.3 это считается архитектурным конфликтом.
Если ошибка возникла внезапно у конкретного пользователя, самым быстрым способом будет очистка кэшированных настроек формы. Рассмотрим, как это сделать без изменения кода.
В форме, где возникает ошибка, найдем командную панель динамического списка. Нажмем кнопку «Ещё» и выберем пункт «Установить стандартные настройки». После этого необходимо закрыть форму и открыть её заново. В многих случаях это очищает конфликтные пользовательские отборы, которые «наложились» на программные после обновления платформы.
Если интерфейс не позволяет добраться до кнопки «Ещё» из-за модального окна ошибки, воспользуемся административным разделом (на примере УТ 11):
Рассмотрим ситуацию с точки зрения разработчика. Часто ошибка возникает из-за того, что программный код установки отборов срабатывает многократно, наслаивая элементы друг на друга. Проанализируем пример правильной установки параметров в событии ПриСозданииНаСервере.
Перед тем как добавлять новый элемент отбора в ФиксированныеНастройки, крайне важно убедиться, что коллекция пуста. Посмотрим на пример кода:
// Очищаем старые элементы, чтобы избежать пересечения
Список.ФиксированныеНастройки.Отбор.Элементы.Очистить();
// Добавляем новый элемент отбора правильно
НовыйЭлемент = Список.ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйЭлемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("СтатусОтгрузки");
НовыйЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
НовыйЭлемент.ПравоеЗначение = Перечисления.СтатусыОтгрузки.КОтгрузке;
НовыйЭлемент.Использование = Истина;
Использование метода Очистить() гарантирует, что при повторном вызове кода или обновлении формы старые значения не вступят в конфликт с новыми.
Если нам нужно, чтобы программный отбор был виден пользователю и он мог его менять (и при этом не возникало ошибки пересечения), следует использовать свойство ИдентификаторПользовательскойНастройки. Рассмотрим, как это работает.
Когда мы задаем идентификатор, платформа понимает, что этот элемент отбора относится к уровню пользовательских настроек, и связывает его с элементами в окне настройки списка. Если идентификатор не задан, а поле совпадает — получаем конфликт. Если же мы хотим «жесткий» отбор, мы помещаем его в ФиксированныеНастройки, но тогда должны убедиться, что этого поля нет в пользовательских настройках в конфигураторе.
Проанализируем настройки динамического списка в конфигураторе. Откроем свойства ДинамическийСписок, перейдем в «Настройки компоновки данных».
Важное правило для 8.3: Если вы планируете устанавливать отбор по полю Контрагент программно через фиксированные настройки, удалите любые упоминания поля Контрагент со вкладки «Отбор» в конфигураторе. Наличие поля в дизайнере СКД создает «предустановленный» отбор, который конфликтует с программным при первом же запуске.
В некоторых случаях, когда логика формы подразумевает очень сложную динамическую смену отборов, проще всего запретить платформе запоминать состояние фильтров пользователя. Для этого в свойствах динамического списка (в конфигураторе) найдем флаг АвтоматическоеСохранениеПользовательскихНастроек и установим его в значение Ложь.
Это радикальный метод, так как пользователи потеряют возможность сохранять свои фильтры после закрытия формы, но он гарантированно лечит ошибку «пересечения», так как уровень пользовательских настроек всегда будет чист при открытии.
Иногда проблема кроется глубже — в серверном кэше или работе расширений. Рассмотрим еще два нюанса:
snccntx в каталоге сервера приложений.Таким образом, мы выяснили, что ключ к решению проблемы — в строгом разделении ответственности между конфигуратором, программным кодом и пользовательскими действиями. Перенос всех «жестких» фильтров в программный код с предварительной очисткой ФиксированныеНастройки — самый надежный путь для стабильной работы в среде 1С 8.3.