Почему динамический список в расширении 1С не виден в коде и как это исправить

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

При разработке в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда новый реквизит формы (например, ДинамическийСписок), добавленный через расширение, отказывается распознаваться платформой. При попытке обращения к нему в модуле формы или в серверных процедурах возникает критическая ошибка «Переменная не определена». Рассмотрим подробно, почему это происходит и как правильно интегрировать динамические списки в расширения, чтобы они работали стабильно.

Анализ проблемы: почему платформа «теряет» реквизит

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

  1. Конфликт контекстов: Использование аннотаций &Перед или &После. В этих случаях платформа может пытаться скомпилировать код в контексте основной конфигурации, где вашего списка еще не существует.
  2. Metadata Corruption (Повреждение метаданных): Внутренняя ошибка платформы, при которой визуально список на форме есть, но в реестре объектов расширения он не зарегистрирован корректно.
  3. Ошибки кэширования: Серверный или локальный кэш хранит старую структуру формы без учета изменений в расширении.
  4. Неправильное обращение: Попытка обращения через ЭтотОбъект, который в управляемых формах может вести себя специфично, или использование кириллицы/латиницы в именах.

Решение 1: Радикальное пересоздание реквизита

Как показывает практика и опыт участников обсуждения, наиболее действенным методом при возникновении «невидимости» является полное удаление и повторное добавление реквизита. Проанализируем, как сделать это правильно:

  1. Удалим проблемный ДинамическийСписок из расширения.
  2. Сохраним расширение и обновим конфигурацию базы данных.
  3. Добавим список заново, присвоив ему уникальное имя.
  4. Если это не помогло, попробуем «шаманский», но эффективный метод: временно изменим тип реквизита на Строка, сохранимся, а затем вернем тип ДинамическийСписок. Это заставляет платформу принудительно перезаписать XML-структуру формы в расширении.

Решение 2: Переход на аннотацию &Вместо

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

Проанализируем пример правильного переопределения процедуры для работы с новым списком СписокРецептур:


&НаКлиенте
&Вместо("СписокПриАктивизацииСтроки")
Процедура БХ_СписокПриАктивизацииСтрокиВместо(Элемент)
    // Получаем данные из основного списка
    ТекущиеДанные = Элемент.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;

    СсылкаНаНоменклатуру = ТекущиеДанные.Ссылка;
    
    // Вызываем серверную процедуру для фильтрации нашего нового списка в расширении
    БХ_ОбновитьСписокРецептурНаСервере(СсылкаНаНоменклатуру);
КонецПроцедуры

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

Решение 3: Программная настройка отборов на сервере

Рассмотрим подробнее, как работать с КомпоновщикНастроек динамического списка, добавленного в расширение. Часто ошибка возникает из-за неправильного обращения к коллекции отборов. Разберем правильный алгоритм установки фильтра по номенклатуре:


&НаСервере
Процедура БХ_ОбновитьСписокРецептурНаСервере(Ном)
    // Обращаемся напрямую к реквизиту формы, добавленному в расширении
    Отбор = СписокРецептур.КомпоновщикНастроек.Настройки.Отбор;
    
    ПолеНоменклатура = Новый ПолеКомпоновкиДанных("Номенклатура");
    ЭлементОтбораНом = Неопределено;

    // Ищем существующий элемент отбора, чтобы не плодить дубли
    Для Каждого Элемент Из Отбор.Элементы Цикл
        Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") 
            И Элемент.ЛевоеЗначение = ПолеНоменклатура Тогда
            ЭлементОтбораНом = Элемент;
            Прервать;
        КонецЕсли;
    КонецЦикла;

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

    // Устанавливаем значение и включаем использование
    ЭлементОтбораНом.ПравоеЗначение = Ном;
    ЭлементОтбораНом.Использование = ЗначениеЗаполнено(Ном);
КонецПроцедуры

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

Решение 4: Использование «Основного реквизита» и прав доступа

Проанализируем еще две неочевидные причины. Иногда список «не виден» из-за ограничений прав или особенностей инициализации формы.

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

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

Резюме и рекомендации

Подводя итог, если вы столкнулись с тем, что 1С не видит динамический список в расширении, выполните следующие шаги в строгом порядке:

  1. Проверьте написание имени (отсутствие латинских букв в кириллическом названии).
  2. Попробуйте обратиться к списку через коллекцию элементов: Элементы.ИмяВашегоСписка (для визуальных свойств) или напрямую по имени (для данных).
  3. Выполните очистку кэша конфигурации (локального и серверного).
  4. Самый эффективный способ: Удалите форму или конкретный реквизит из расширения и добавьте его заново «с нуля».
  5. Убедитесь, что код расширения не конфликтует с кодом основной конфигурации, используя аннотацию &Вместо для критичных участков логики.

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

← На главную