Разработка и Конфигурация · 7 мин
Как узнать, есть ли реквизит у документа 1С
Способы проверить наличие реквизита у документа 1С: через конфигуратор, метаданные и код на встроенном языке. Примеры, ошибки и граничные случаи.
Проверка наличия реквизита у документа — одна из самых частых задач при доработке конфигураций 1С. Она нужна, когда код должен работать с разными видами документов, когда конфигурация обновляется и реквизиты могут появляться или исчезать, либо когда обработка должна корректно работать в нескольких базах с разными версиями. Прямое обращение к несуществующему реквизиту вызывает ошибку «Поле объекта не обнаружено», поэтому безопасная проверка — обязательный приём в универсальном коде.
Существует несколько способов решения задачи: визуальный просмотр в конфигураторе, программная проверка через коллекцию метаданных и косвенные методы вроде попытки обращения с обработкой исключения. Каждый подходит для своей ситуации: разработчику удобнее конфигуратор, а в выполняемом коде правильнее использовать объектную модель метаданных.
Проверка реквизита в конфигураторе
Самый простой способ убедиться, что реквизит существует, — открыть структуру документа в конфигураторе. В дереве конфигурации найдите ветку «Документы», раскройте нужный вид документа и откройте узел «Реквизиты». Там перечислены все реквизиты шапки вместе с типами и свойствами.
Табличные части проверяются отдельно: реквизиты табличной части находятся внутри узла «Табличные части» в соответствующей ветке. Частая ошибка — искать реквизит табличной части в общем списке реквизитов документа и делать вывод, что его нет.
Удобный приём — открыть палитру свойств документа и воспользоваться поиском по дереву конфигурации (Ctrl+F в окне конфигурации). Если реквизит добавлен расширением, он отображается в дереве расширения, а не основной конфигурации, и это тоже нужно учитывать при поиске.
Проверка через метаданные в коде
Основной программный способ — обращение к объекту метаданных документа. Коллекция Реквизиты имеет метод Найти(), который возвращает описание реквизита или Неопределено, если реквизита нет.
Функция ЕстьРеквизитДокумента(ДокументОбъект, ИмяРеквизита)
МетаданныеДокумента = ДокументОбъект.Метаданные();
Возврат МетаданныеДокумента.Реквизиты.Найти(ИмяРеквизита) <> Неопределено;
КонецФункции
Функция универсальна: её можно вызывать для любого документа, передавая объект или получая метаданные по ссылке — ДокументСсылка.Метаданные() работает так же. Это позволяет проверять реквизиты без открытия объекта, что быстрее и безопаснее по блокировкам.
Если Документ.Метаданные().Реквизиты.Найти("Комментарий") <> Неопределено Тогда
Документ.Комментарий = "Заполнено программно";
КонецЕсли;Если нужно проверить реквизит по имени вида документа без ссылки, используйте менеджер: Метаданные.Документы.Найти(\"РеализацияТоваровУслуг\").Реквизиты.Найти(\"ИмяРеквизита\"). Этот вариант подходит, когда проверка выполняется до создания или получения самого документа.
Проверка реквизитов табличной части
Реквизиты табличных частей находятся в отдельной коллекции, и проверка строится в два шага: сначала убедиться, что существует сама табличная часть, затем искать реквизит внутри неё.
МетаданныеДокумента = Документ.Метаданные();
ТабличнаяЧасть = МетаданныеДокумента.ТабличныеЧасти.Найти("Товары");
Если ТабличнаяЧасть <> Неопределено Тогда
ЕстьРеквизит = ТабличнаяЧасть.Реквизиты.Найти("Скидка") <> Неопределено;
КонецЕсли;
Пропуск проверки табличной части — типичный источник ошибок в универсальных обработках: в одном виде документа табличная часть «Товары» есть, в другом — нет, и обращение к ней приводит к падению кода ещё до проверки реквизита.
Стандартные реквизиты и невидимые поля
Коллекция Реквизиты не содержит стандартные реквизиты документа: «Номер», «Дата», «Проведен», «Ссылка» и другие. Они перечислены в коллекции СтандартныеРеквизиты. Если нужно проверить наличие любого поля, включая стандартные, проверяйте обе коллекции.
Также учитывайте общие реквизиты конфигурации: если реквизит добавлен как общий, он может не отображаться в дереве реквизитов конкретного документа, но при этом быть доступным у объекта. Проверка через метаданные документа в этом случае зависит от настройки состава общего реквизита, поэтому надёжнее дополнительно проверить коллекцию Метаданные.ОбщиеРеквизиты.
Альтернатива: обращение через попытку
Иногда вместо проверки метаданных используют конструкцию Попытка ... Исключение с прямым обращением к реквизиту. Такой подход работает, но считается менее корректным: исключения медленнее, затрудняют отладку и маскируют реальные ошибки внутри блока.
Использовать «Попытку» оправдано лишь в редких случаях — например, когда проверяется доступность свойства у произвольного объекта неизвестного типа. Для документов проверка через метаданные предпочтительнее всегда.
Проверка результата и практические рекомендации
После внедрения проверки убедитесь, что код корректно отрабатывает обе ветки: когда реквизит есть и когда его нет. Протестируйте на копии базы с документами разных видов, для которых предназначена обработка. Особое внимание уделите документам, где реквизит появился в новых релизах конфигурации.
Полезная практика — кэшировать результат проверки, если она выполняется в цикле: обращение к метаданным недорогое, но в массовых обработках накопительный эффект заметен. Сохраните результат в соответствие вида «имя документа — признак наличия реквизита» и используйте повторно.
Как проверить результат
Возвращается Истина
Возвращается Ложь — ошибка в имени реквизита или коллекции
Возвращается Ложь без исключений
Возникает ошибка выполнения
Результат соответствует дереву метаданных в конфигураторе
Расхождение — проверьте имя табличной части
Частые вопросы
Как проверить наличие реквизита у ссылки, не открывая объект?
У ссылки доступен метод Метаданные(): Ссылка.Метаданные().Реквизиты.Найти("Имя"). Получать объект через ПолучитьОбъект() для этого не требуется, что экономит ресурсы и не создаёт блокировок.
Почему Найти() возвращает Неопределено, хотя реквизит виден в форме?
Вероятные причины: реквизит добавлен расширением конфигурации, это реквизит формы (а не объекта), либо это общий реквизит, не включённый в состав данного документа. Проверьте источник поля в дереве конфигурации.
Как проверить реквизит у всех видов документов сразу?
Пройдите циклом по Метаданные.Документы и для каждого вида вызовите Реквизиты.Найти("Имя"). Результат удобно собрать в таблицу значений: вид документа и признак наличия реквизита.
Работает ли проверка на толстом и тонком клиенте?
Доступ к метаданным документов доступен везде, но на тонком и веб-клиенте объектная модель ограничена. Надёжнее выполнять такие проверки в серверных процедурах и функциях.
Чем проверка через метаданные лучше Попытка/Исключение?
Проверка метаданных не генерирует исключений, работает быстрее, не мешает отладке и явно документирует намерение кода. Исключения оставляйте для действительно нештатных ситуаций.
Что важно запомнить
Наличие реквизита проверяется через Метаданные().Реквизиты.Найти(Имя): Неопределено означает отсутствие. Стандартные и общие реквизиты, а также реквизиты табличных частей проверяются в отдельных коллекциях. Проверка по ссылке не требует открытия объекта.