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

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

Как узнать, есть ли реквизит у документа 1С

Способы проверить наличие реквизита у документа 1С: через конфигуратор, метаданные и код на встроенном языке. Примеры, ошибки и граничные случаи.

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

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

Проверка реквизита в конфигураторе

Самый простой способ убедиться, что реквизит существует, — открыть структуру документа в конфигураторе. В дереве конфигурации найдите ветку «Документы», раскройте нужный вид документа и откройте узел «Реквизиты». Там перечислены все реквизиты шапки вместе с типами и свойствами.

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

Удобный приём — открыть палитру свойств документа и воспользоваться поиском по дереву конфигурации (Ctrl+F в окне конфигурации). Если реквизит добавлен расширением, он отображается в дереве расширения, а не основной конфигурации, и это тоже нужно учитывать при поиске.

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

Основной программный способ — обращение к объекту метаданных документа. Коллекция Реквизиты имеет метод Найти(), который возвращает описание реквизита или Неопределено, если реквизита нет.

Функция ЕстьРеквизитДокумента(ДокументОбъект, ИмяРеквизита)

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

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

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

Функция универсальна: её можно вызывать для любого документа, передавая объект или получая метаданные по ссылке — ДокументСсылка.Метаданные() работает так же. Это позволяет проверять реквизиты без открытия объекта, что быстрее и безопаснее по блокировкам.

bsl
Если Документ.Метаданные().Реквизиты.Найти("Комментарий") <> Неопределено Тогда
    Документ.Комментарий = "Заполнено программно";
КонецЕсли;

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

Проверка реквизитов табличной части

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

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

ТабличнаяЧасть = МетаданныеДокумента.ТабличныеЧасти.Найти("Товары");

Если ТабличнаяЧасть <> Неопределено Тогда

ЕстьРеквизит = ТабличнаяЧасть.Реквизиты.Найти("Скидка") <> Неопределено;

КонецЕсли;

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

Стандартные реквизиты и невидимые поля

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

Также учитывайте общие реквизиты конфигурации: если реквизит добавлен как общий, он может не отображаться в дереве реквизитов конкретного документа, но при этом быть доступным у объекта. Проверка через метаданные документа в этом случае зависит от настройки состава общего реквизита, поэтому надёжнее дополнительно проверить коллекцию Метаданные.ОбщиеРеквизиты.

Альтернатива: обращение через попытку

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

Использовать «Попытку» оправдано лишь в редких случаях — например, когда проверяется доступность свойства у произвольного объекта неизвестного типа. Для документов проверка через метаданные предпочтительнее всегда.

Типичные ошибки
01
Поиск стандартного реквизита (Номер, Дата) в коллекции Реквизиты — его там нет, проверяйте СтандартныеРеквизиты
02
Поиск реквизита табличной части в общем списке реквизитов документа
03
Обращение к табличной части без проверки её существования
04
Использование Попытка/Исключение вместо проверки метаданных — код медленнее и скрывает ошибки
05
Игнорирование реквизитов, добавленных расширением конфигурации

Проверка результата и практические рекомендации

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

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

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

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

Вызов функции проверки для реквизита, который точно существует
Норма

Возвращается Истина

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

Возвращается Ложь — ошибка в имени реквизита или коллекции

Вызов для заведомо отсутствующего реквизита
Норма

Возвращается Ложь без исключений

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

Возникает ошибка выполнения

Проверка реквизита табличной части
Норма

Результат соответствует дереву метаданных в конфигураторе

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

Расхождение — проверьте имя табличной части

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

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

У ссылки доступен метод Метаданные(): Ссылка.Метаданные().Реквизиты.Найти("Имя"). Получать объект через ПолучитьОбъект() для этого не требуется, что экономит ресурсы и не создаёт блокировок.

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

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

Как проверить реквизит у всех видов документов сразу?

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

Работает ли проверка на толстом и тонком клиенте?

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

Чем проверка через метаданные лучше Попытка/Исключение?

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

Итог

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

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