Как правильно настроить отбор динамического списка в 1С 8.3 и избежать ошибки «Индекс за пределами массива»?

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

При переходе конфигураций с платформы 1С 8.2 на 1С 8.3 (при отключении режима совместимости) разработчики часто сталкиваются с ошибкой «Индекс находится за границами массива» при попытке программно обратиться к первому элементу отбора динамического списка: Список.Отбор.Элементы[0]. Разберем причины такого поведения платформы и подробно рассмотрим надежные способы установки отборов в управляемых формах.

Почему в 1С 8.3 возникает ошибка при обращении к Список.Отбор

Проанализируем архитектурные изменения платформы. В версии 8.3 механизм динамического списка приведен к строгой модели системы компоновки данных (СКД), где настройки разделены на три независимых уровня:

  1. Настройки по умолчанию: коллекция Список.КомпоновщикНастроек.Настройки. Именно сюда попадают элементы отбора, заданные разработчиком в конфигураторе в свойствах динамического списка.
  2. Фиксированные настройки: коллекция Список.КомпоновщикНастроек.ФиксированныеНастройки. Прямое свойство формы Список.Отбор является ссылкой именно на отбор фиксированных настроек. При создании формы без режима совместимости эта коллекция изначально пуста, поэтому прямое обращение по нулевому индексу [0] вызывает исключение.
  3. Пользовательские настройки: коллекция Список.КомпоновщикНастроек.ПользовательскиеНастройки. Сюда попадают элементы, для которых в конфигураторе или коде включен признак отображения пользователю.

Таким образом, отборы, настроенные в конфигураторе, не попадают в Список.Отбор автоматически. Рассмотрим различные практические варианты решения задачи.

Способ 1. Программное добавление и поиск элементов в фиксированном отборе

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

Посмотрим на пример безопасной установки отбора на сервере:


ПолеОтбора = Новый ПолеКомпоновкиДанных("Владелец");
Элемент = Неопределено;

Для Каждого ЭлементКоллекции Из Список.Отбор.Элементы Цикл
    Если ЭлементКоллекции.ЛевоеЗначение = ПолеОтбора Тогда
        Элемент = ЭлементКоллекции;
        Прервать;
    КонецЕсли;
КонецЦикла;

Если Элемент = Неопределено Тогда
    Элемент = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    Элемент.ЛевоеЗначение = ПолеОтбора;
КонецЕсли;

Элемент.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Элемент.ПравоеЗначение = НужныйВладелец;
Элемент.Использование = Истина;

Способ 2. Изменение отборов, заданных в конфигураторе

Если отбор уже был настроен в конфигураторе и вам требуется только поменять его значение в коде, обращаться нужно к базовым настройкам компоновщика:


Список.КомпоновщикНастроек.Настройки.Отбор.Элементы[0].ПравоеЗначение = НужныйВладелец;
Список.КомпоновщикНастроек.Настройки.Отбор.Элементы[0].Использование = Истина;

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

Способ 3. Передача отбора через параметры формы (декларативный подход)

В управляемом приложении 1С 8.3 нет необходимости писать программный код фильтрации в обработчике ПриСозданииНаСервере, если форму нужно открыть с уже установленным отбором. Достаточно передать структуру отбора в параметрах вызова формы:


ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", Новый Структура("Владелец", ЗначениеВладельца));

ОткрытьФорму("Справочник.Контрагенты.ФормаСписка", ПараметрыФормы, ЭтотОбъект);

Платформа автоматически применит указанные поля к динамическому списку при инициализации формы.

Способ 4. Использование параметров произвольного запроса списка

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

  1. В тексте запроса динамического списка прописываем условие: ГДЕ Таблица.Владелец = &Владелец.
  2. В коде формы на сервере устанавливаем значение параметра:

Список.Параметры.УстановитьЗначениеПараметра("Владелец", ЗначениеВладельца);

Такой подход полностью исключает коллизии между пользовательскими фильтрами и логикой конфигурации.

Способ 5. Использование типовых функций Библиотеки стандартных подсистем (БСП)

В конфигурациях, использующих БСП (например, 1C:ERP, УТ 11, КА 2, Бухгалтерия предприятия 3.0), для управления отборами реализованы готовые процедуры общего модуля. Они берут на себя поиск элемента, правильную адресацию и синхронизацию с пользовательскими настройками:


ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
    Список, 
    "Владелец", 
    ЗначениеВладельца, 
    ВидСравненияКомпоновкиДанных.Равно
);

Использование типовых методов является рекомендуемой практикой, так как обеспечивает единообразие кода и защищает от ошибок при обновлении версии платформы.

← На главную