К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как проверить существование табличной части в 1С

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

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

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

Зачем нужна проверка и когда без неё не обойтись

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

Вторая ситуация — доработка типовых конфигураций, где состав объектов может меняться при обновлении. Код, написанный «в лоб», после обновления конфигурации начнёт падать с ошибкой «Поле объекта не обнаружено». Защитная проверка позволяет алгоритму корректно пропустить объект вместо аварийной остановки.

Третий случай — внешние обработки и отчёты, которые подключаются к разным конфигурациям. Одна и та же обработка может использоваться в базах с разным набором документов, и жёсткая привязка к именам табличных частей недопустима.

Проверка через метаданные объекта

Основной способ — обратиться к коллекции табличных частей в метаданных конкретного объекта. У каждого объекта (ссылки или объекта данных) есть метод Метаданные(), который возвращает описание конфигурации этого объекта, включая коллекцию ТабличныеЧасти.

Метод Найти() у коллекции ищет табличную часть по имени. Если табличная часть найдена, метод возвращает объект описания метаданного; если нет — возвращает Неопределено. На этом и строится проверка.

Функция ЕстьТабличнаяЧасть(ОбъектДанных, ИмяТабличнойЧасти)

МетаданныеОбъекта = ОбъектДанных.Метаданные();

Возврат МетаданныеОбъекта.ТабличныеЧасти.Найти(ИмяТабличнойЧасти) <> Неопределено;

КонецФункции

// Пример вызова

Если ЕстьТабличнаяЧасть(ДокументОбъект, "Товары") Тогда

Для Каждого СтрокаТЧ Из ДокументОбъект.Товары Цикл

// обработка строк

КонецЦикла;

КонецЕсли;

Обратите внимание: проверка регистронезависима только для имён, заданных в конфигураторе, но лучше всегда указывать имя точно так, как оно задано в метаданных — это исключает ошибки при переносе кода между конфигурациями.

Проверка по метаданным вида документа без объекта

Иногда объекта под рукой нет — известно только имя вида документа строкой. В этом случае обращайтесь к метаданным конфигурации напрямую через менеджер документов.

Функция ЕстьТабличнаяЧастьПоИмениВида(ВидДокумента, ИмяТабличнойЧасти)

МетаданныеДокумента = Метаданные.Документы.Найти(ВидДокумента);

Если МетаданныеДокумента = Неопределено Тогда

Возврат Ложь;

КонецЕсли;

Возврат МетаданныеДокумента.ТабличныеЧасти.Найти(ИмяТабличнойЧасти) <> Неопределено;

КонецФункции

// Пример

Если ЕстьТабличнаяЧастьПоИмениВида("РеализацияТоваровУслуг", "Товары") Тогда

// ...

КонецЕсли;

Такой вариант удобен в обработках, где пользователь выбирает вид документа из списка, а код заранее проверяет, применим ли алгоритм к этому виду. Для справочников аналогично используется коллекция Метаданные.Справочники.

Проверка через конструкцию Попытка...Исключение

Альтернативный подход — попытаться обратиться к табличной части и перехватить ошибку. Этот способ медленнее и считается менее «чистым», но он универсален: работает даже тогда, когда тип переменной заранее неизвестен и непонятно, есть ли у неё вообще метаданные.

Функция ЕстьТабличнаяЧастьПопыткой(ОбъектДанных, ИмяТабличнойЧасти)

Попытка

ТестоваяКоллекция = ОбъектДанных[ИмяТабличнойЧасти];

Возврат ТипЗнч(ТестоваяКоллекция) <> Тип("Неопределено");

Исключение

Возврат Ложь;

КонецПопытки;

КонецФункции

Обращение через квадратные скобки ОбъектДанных[ИмяТабличнойЧасти] позволяет использовать имя табличной части как строку-переменную, что удобно в универсальных алгоритмах. Однако помните: исключения во встроенном языке 1С — ресурсоёмкая операция, и в циклах по тысячам объектов такой подход заметно замедлит выполнение.

Сравнение способов проверки

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

СпособКогда применятьОграничения
Объект.Метаданные().ТабличныеЧасти.Найти()Есть ссылка или объект, тип неизвестен заранееТребует, чтобы у переменной был метод Метаданные()
Метаданные.Документы[Вид].ТабличныеЧасти.Найти()Известен только вид документа строкойНужна отдельная ветка для каждого типа коллекции (справочники, документы)
Попытка...ИсключениеТип переменной совершенно неизвестенМедленнее, скрывает прочие ошибки
Маршрут решения

Как выбрать действие

Есть ссылка или объект документа/справочникаИспользуйте Объект.Метаданные().ТабличныеЧасти.Найти(Имя)
Известно только имя вида документа строкойОбратитесь к Метаданные.Документы.Найти(Вид), затем к коллекции ТабличныеЧасти
Тип переменной неизвестен и может быть произвольнымОберните обращение в Попытка...Исключение
Проверка выполняется в цикле по большому числу объектовКэшируйте результат проверки по виду объекта, чтобы не вызывать Метаданные() повторно

Проверка в запросе и на форме

Через текст запроса

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

Практический приём — собирать текст запроса строкой, добавляя объединения только для тех видов документов, где табличная часть реально есть:

Для Каждого МетаДок Из Метаданные.Документы Цикл

Если МетаДок.ТабличныеЧасти.Найти("Товары") = Неопределено Тогда

Продолжить;

КонецЕсли;

// добавить в текст запроса выборку из Документ." + МетаДок.Имя + ".Товары

КонецЦикла;

Проверка на управляемой форме

Когда код выполняется в модуле формы, табличная часть обычно доступна как реквизит формы или как свойство объекта в данных формы. Для проверки наличия элемента формы (таблицы) используйте поиск в коллекции Элементы: Элементы.Найти("Товары") — вернёт Неопределено, если таблица не выведена на форму.

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

Контрольные точки

Как проверить результат

Значение, возвращаемое Найти()
Норма

Неопределено — табличной части нет, код идёт по ветке пропуска

Тревожный признак

Ошибка выполнения — значит, проверка написана не для того типа объекта

Поведение обработки на документе без нужной ТЧ
Норма

Документ пропускается без ошибки, в журнале нет записей об исключениях

Тревожный признак

Обработка прерывается с сообщением «Поле объекта не обнаружено»

Скорость массовой обработки
Норма

Время выполнения стабильно, проверка не вызывается повторно для одного вида

Тревожный признак

Заметное замедление на каждом объекте — вероятно, лишние вызовы Метаданные() или исключения

Типичные ошибки и ограничения

Самая частая ошибка — проверка наличия табличной части у переменной, которая может содержать Неопределено или значение примитивного типа. Вызов Метаданные() у такого значения сам вызовет ошибку. Перед проверкой убедитесь, что переменная содержит ссылку или объект нужного типа, например через ТипЗнч() или проверку на Неопределено.

Вторая ошибка — путать табличные части с реквизитами составного типа. Коллекция ТабличныеЧасти содержит только табличные части; реквизиты ищутся в коллекции Реквизиты, а стандартные реквизиты — в СтандартныеРеквизиты. Если Найти() вернул Неопределено, убедитесь, что вы ищете в правильной коллекции.

Третья ошибка — игнорирование кэширования. Вызов Метаданные() сам по себе быстрый, но в цикле по десяткам тысяч объектов одного вида разумно проверить табличную часть один раз для вида и хранить результат в соответствии.

Типичные ошибки
01
Вызов Метаданные() у Неопределено или строки — получение ошибки вместо проверки; сначала проверьте тип значения
02
Поиск реквизита в коллекции ТабличныеЧасти — результат всегда Неопределено; реквизиты ищутся в коллекции Реквизиты
03
Использование Попытка...Исключение внутри цикла по тысячам объектов — сильное замедление; замените на проверку метаданных с кэшированием
04
Смешение проверки метаданных и проверки элемента формы — табличная часть может существовать у объекта, но отсутствовать на форме

Итоговые рекомендации

Для большинства задач достаточно одной универсальной функции-помощника, построенной на проверке метаданных. Разместите её в общем модуле, чтобы использовать во всех доработках, и дополните проверкой типа входного параметра — это сделает код устойчивым к неожиданным значениям.

Конструкцию Попытка...Исключение оставьте для действительно неопределённых ситуаций, когда тип переменной невозможно предсказать. В массовых обработках кэшируйте результаты проверок по видам объектов — это даст заметный выигрыш в производительности без усложнения логики.

Итог

Что важно запомнить

Проверка существования табличной части делается через Метаданные().ТабличныеЧасти.Найти(Имя): Неопределено означает отсутствие. Перед проверкой убедитесь, что переменная содержит объект с метаданными, а в массовых обработках кэшируйте результат по виду объекта.

Частые вопросы

Можно ли проверить табличную часть у объекта, не получая его из базы?

Да. Достаточно ссылки: у любой ссылки есть метод Метаданные(), через который доступна коллекция ТабличныеЧасти. Получать объект методом ПолучитьОбъект() для проверки не требуется — это быстрее и безопаснее для больших выборок.

Чем отличается проверка табличной части от проверки реквизита?

Это разные коллекции метаданных. Табличные части ищутся в Метаданные().ТабличныеЧасти, а реквизиты шапки — в Метаданные().Реквизиты. Если поиск в одной коллекции вернул Неопределено, проверьте, не относится ли искомое к другой коллекции.

Почему Найти() возвращает Неопределено, хотя табличная часть точно есть?

Чаще всего дело в неточном имени: лишний пробел, другое написание или имя задано с опечаткой. Скопируйте имя табличной части прямо из конфигуратора. Также проверьте, что вы ищете в метаданных правильного объекта — например, не перепутаны виды документов.

Работает ли проверка для табличных частей справочников и планов счетов?

Да, механизм одинаков для всех объектов, у которых есть табличные части: справочников, документов, планов счетов, планов видов расчёта и других. Меняется только путь к метаданным вида при проверке без объекта: Метаданные.Справочники, Метаданные.ПланыСчетов и так далее.

Как проверить наличие табличной части, если объект пришёл как строка с именем типа?

Сначала получите описание метаданных по имени: Метаданные.НайтиПоПолномуИмени("Документ.РеализацияТоваровУслуг"). Если результат не Неопределено, обратитесь к его коллекции ТабличныеЧасти и выполните Найти() по имени табличной части.

Есть ли готовая функция проверки в БСП?

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