Как проверить наличие свойства «Основная таблица» у динамического списка в 1С?

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

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

Почему свойство «Основная таблица» может отсутствовать

Проанализируем поведение платформы. Объект ДинамическийСписок оптимизирован для работы с памятью. Если у списка установлен флаг ПроизвольныйЗапрос, наличие основной таблицы становится необязательным. В некоторых версиях платформы или при определенных манипуляциях в Runtime-контексте, если таблица не указана, свойство просто исключается из объекта. Это означает, что обращение Список.ОсновнаяТаблица вызовет исключение «Поле объекта не обнаружено».

Рассмотрим основные ситуации, когда это критично:

  1. При создании универсальных обработок, которые анализируют форму.
  2. При программной модификации текста запроса динамического списка.
  3. При необходимости динамически определить, к каким метаданным привязан список для активации стандартных команд (создание, копирование).

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

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

Выясним, как проверить наличие свойства:


// Возвращает Истина, если свойство существует в объекте
ЕстьСвойство = ОбщегоНазначения.ЕстьРеквизитИлиСвойствоОбъекта(Элементы.Список, "ОсновнаяТаблица");

Если ЕстьСвойство Тогда
    ИмяТаблицы = Элементы.Список.ОсновнаяТаблица;
КонецЕсли;

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


ИмяТаблицы = ОбщегоНазначения.ЗначениеСвойстваОбъекта(Элементы.Список, "ОсновнаяТаблица", "");

Способ 2. Универсальная функция на основе ЗаполнитьЗначенияСвойств

Рассмотрим очень элегантный способ, который предложили участники сообщества. Он основан на работе метода ЗаполнитьЗначенияСвойств. Этот метод копирует значения из одного объекта в другой по совпадению имен свойств, при этом он игнорирует отсутствующие свойства, не вызывая ошибок. Это позволяет нам создать «детектор» наличия свойства.

Разберем реализацию этой функции пошагово:


Функция ЗначениеСвойстваОбъекта(Объект, ИмяСвойства, ЗначениеПоУмолчанию = Неопределено) Экспорт
    // Создаем структуру с искомым именем свойства
    Структура = Новый Структура(ИмяСвойства, ЗначениеПоУмолчанию);
    
    // Пытаемся заполнить структуру из объекта
    // Если в объекте нет свойства "ИмяСвойства", структура останется без изменений
    ЗаполнитьЗначенияСвойств(Структура, Объект);
    
    Возврат Структура[ИмяСвойства];
КонецФункции

// Пример использования для проверки Основной Таблицы
ИмяТаблицы = ЗначениеСвойстваОбъекта(ДинамическийСписок, "ОсновнаяТаблица");
ЕстьОсновнаяТаблица = ЗначениеЗаполнено(ИмяТаблицы);

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

Способ 3. Использование блока Попытка...Исключение

Проанализируем самый простой и очевидный метод. Если нам нужно разово проверить свойство, мы можем просто попытаться к нему обратиться. Несмотря на то, что использование исключений для логики программы считается не лучшей практикой (из-за влияния на производительность), в простых сценариях это допустимо.

Посмотрим на пример кода:


ОсновнаяТаблицаЗадана = Ложь;
Попытка
    ТекТаблица = Список.ОсновнаяТаблица;
    ОсновнаяТаблицаЗадана = ЗначениеЗаполнено(ТекТаблица);
Исключение
    // Свойство отсутствует в контексте объекта
    ОсновнаяТаблицаЗадана = Ложь;
КонецПопытки;

Взаимосвязь с произвольным запросом

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

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

Последствия отсутствия основной таблицы

Проанализируем ситуацию, когда проверка показала отсутствие таблицы. Это напрямую влияет на интерфейс и функциональность приложения:

Таким образом, мы рекомендуем использовать метод через ЗаполнитьЗначенияСвойств или функции ОбщегоНазначения из БСП для обеспечения стабильной работы ваших программных механизмов при взаимодействии с динамическими списками.

← На главную