Разработка и Конфигурация · 11 мин
Как перебрать все реквизиты объекта в 1С
Как перебрать все реквизиты объекта в 1С через метаданные: цикл по реквизитам, табличным частям, проверка заполненности, типовые ошибки и готовые примеры кода.
Перебор всех реквизитов объекта — типовая задача в 1С: она нужна при универсальном заполнении, сравнении объектов, выгрузке данных, поиске незаполненных полей и миграции между конфигурациями. Прямого свойства «список реквизитов» у объекта нет — перебор выполняется через коллекцию метаданных, к которой обращаются из кода.
Ключевая идея проста: у любого прикладного объекта (справочника, документа, плана видов характеристик и т.д.) есть метод Метаданные(), возвращающий описание его структуры. У этого описания есть коллекция Реквизиты, по которой можно пройтись циклом и через строковое имя обратиться к значению каждого реквизита у конкретного объекта.
Ниже разобраны рабочие примеры для обычных реквизитов, стандартных реквизитов и табличных частей, а также ограничения подхода и типичные ошибки, из-за которых универсальные обработки «падают» на реальных базах.
Базовый способ: цикл по коллекции метаданных
Основной приём — обойти коллекцию Метаданные().Реквизиты и для каждого элемента прочитать значение по имени. Это работает для справочников, документов, планов счетов, планов видов характеристик, бизнес-процессов и задач.
ОбъектМетаданные = Объект.Метаданные();
Для Каждого Реквизит Из ОбъектМетаданные.Реквизиты Цикл
ИмяРеквизита = Реквизит.Имя;
Значение = Объект[ИмяРеквизита];
Сообщить(ИмяРеквизита + " = " + Значение);
КонецЦикла;
Объект в этом примере — это либо объект данных, полученный методом ПолучитьОбъект() по ссылке, либо ДанныеФормыСтруктура/реквизит формы на управляемой форме после преобразования. Важно понимать: у ссылки (СправочникСсылка, ДокументСсылка) метода Метаданные() тоже есть, поэтому перебрать имена реквизитов можно и без получения объекта, а вот значения у ссылки читаются напрямую — они доступны через точку.
У каждого элемента коллекции доступны полезные свойства: Имя, Синоним, Тип (объект ОписаниеТипов), Комментарий, ПроверкаЗаполнения. Это позволяет строить универсальные механизмы: например, выводить пользователю синонимы вместо служебных имён или проверять, допускает ли реквизит строковый тип.
Для Каждого Реквизит Из Объект.Метаданные().Реквизиты Цикл
Значение = Объект[Реквизит.Имя];
Сообщить(Реквизит.Синоним + " = " + Значение);
КонецЦикла;Перебор стандартных реквизитов
Коллекция Реквизиты содержит только реквизиты, добавленные разработчиком в конфигураторе. Стандартные поля — Код, Наименование, Номер, Дата, ПометкаУдаления, Проведен, Ссылка, Владелец, Родитель — в неё не входят. Для них существует отдельная коллекция СтандартныеРеквизиты.
Для Каждого СтандартныйРеквизит Из Объект.Метаданные().СтандартныеРеквизиты Цикл
Значение = Объект[СтандартныйРеквизит.Имя];
Сообщить(СтандартныйРеквизит.Имя + " = " + Значение);
КонецЦикла;
Нюанс: состав стандартных реквизитов зависит от настроек объекта. Если у справочника длина наименования установлена в ноль, реквизита «Наименование» в коллекции не будет. У непроводимого документа нет реквизита «Проведен». Поэтому перебор через метаданные безопаснее, чем жёстко прописанный список имён — код сам подстроится под конкретную конфигурацию.
Если нужен полный перечень «всех полей», объедините оба цикла: сначала стандартные реквизиты, затем пользовательские. Не забудьте, что значение стандартного реквизита «Ссылка» у объекта совпадает с самой ссылкой, а «ПометкаУдаления» имеет булев тип.
Перебор табличных частей и их реквизитов
Табличные части — отдельная коллекция метаданных ТабличныеЧасти. У каждой табличной части есть своя коллекция Реквизиты, и перебор строится вложенным циклом: сначала по табличным частям, затем по строкам, затем по реквизитам строки.
Для Каждого ТабЧасть Из Объект.Метаданные().ТабличныеЧасти Цикл
Для Каждого Строка Из Объект[ТабЧасть.Имя] Цикл
Для Каждого РеквизитТЧ Из ТабЧасть.Реквизиты Цикл
Значение = Строка[РеквизитТЧ.Имя];
Сообщить(ТабЧасть.Имя + "." + РеквизитТЧ.Имя + " = " + Значение);
КонецЦикла;
КонецЦикла;
КонецЦикла;
Обращение к значению идёт через строку табличной части, а не через саму табличную часть — частая ошибка новичков. Также учитывайте, что у табличной части есть стандартный реквизит «НомерСтроки», который в коллекцию Реквизиты не входит.
Практические сценарии использования
Проверка заполненности всех реквизитов
Типовая задача — найти незаполненные реквизиты, которые в конфигураторе помечены как обязательные. Для этого проверяется свойство ПроверкаЗаполнения и значение через функцию ЗначениеЗаполнено():
Для Каждого Реквизит Из Объект.Метаданные().Реквизиты Цикл
Если Реквизит.ПроверкаЗаполнения = ПроверкаЗаполнения.ВыдаватьОшибку
И Не ЗначениеЗаполнено(Объект[Реквизит.Имя]) Тогда
Сообщить("Не заполнен реквизит: " + Реквизит.Синоним);
КонецЕсли;
КонецЦикла;
Сравнение двух объектов
Для сравнения двух объектов одного вида достаточно пройти по реквизитам первого и сравнить значения со вторым. Учтите, что ссылочные значения корректно сравниваются оператором равенства, а табличные части так сравнить нельзя — их нужно обходить построчно.
Универсальное копирование данных
При переносе данных между похожими объектами (например, из одного вида документа в другой) перебор по метаданным позволяет копировать только те реквизиты, которые существуют у обоих объектов, с проверкой совместимости типов через Реквизит.Тип.СодержитТип().
- 1Получите описание метаданных: МетаданныеОбъекта = Объект.Метаданные()
- 2Пройдите циклом по МетаданныеОбъекта.Реквизиты и читайте значения как Объект[Реквизит.Имя]
- 3При необходимости добавьте цикл по СтандартныеРеквизиты для Кода, Наименования, Номера, Даты
- 4Для табличных частей добавьте вложенный цикл по ТабличныеЧасти и строкам
- 5Проверьте результат на объекте с незаполненными реквизитами и на объекте без табличных частей
Сравнение с альтернативными подходами
Перебор через метаданные — не единственный способ. В зависимости от задачи может быть удобнее запрос или сериализация.
Сравнение вариантов
Подходит для обработки одного объекта в памяти: заполнение, проверка, сравнение. Неэффективен для массовой обработки тысяч записей.
Быстрее при массовой обработке, но требует явного перечисления полей в тексте запроса; универсальность достигается построением текста запроса по метаданным.
Удобна для выгрузки объекта целиком, но не даёт постраничного контроля над отдельными реквизитами.
Для массовой проверки данных по всей таблице (например, найти документы с пустым реквизитом) всегда предпочтительнее запрос: перебор объектов через ПолучитьОбъект() в цикле читает каждую запись целиком и на больших таблицах работает медленно и нагружает сервер.
Типичные ошибки и ограничения
Ещё одно ограничение: перебор по метаданным возвращает реквизиты в порядке их определения в конфигураторе, а не в алфавитном. Если порядок вывода важен (например, для печатной формы или файла), сортируйте имена отдельно — например, через СписокЗначений с сортировкой.
Также помните про права: если у пользователя нет права просмотра отдельных реквизитов (ограничение на уровне записей или функциональных опций), значения могут быть недоступны или объект — не читаться вовсе. В серверных процедурах с признаком «Привилегированный» это ограничение снимается, что нужно учитывать при проектировании безопасности.
Как проверить результат
В списке присутствуют все реквизиты из конфигуратора, включая добавленные недавно
Отсутствуют Код/Наименование/Номер — значит, не перебраны СтандартныеРеквизиты
Для каждой строки выводятся значения всех колонок
Ошибка обращения к свойству или одинаковые значения для всех строк
Цикл по ТабличныеЧасти просто не выполняется, ошибок нет
Код падает из-за жёсткого обращения к конкретной табличной части по имени
Частые вопросы
Можно ли перебрать реквизиты, не получая объект из базы?
Да, если нужны только имена и свойства реквизитов — метаданные доступны и через ссылку: Ссылка.Метаданные().Реквизиты. Значения реквизитов у ссылки тоже читаются напрямую через точку или через Ссылка[ИмяРеквизита], платформа сама выполнит обращение к базе. Получать объект методом ПолучитьОбъект() нужно только для изменения и записи данных.
Почему в цикле не видно реквизиты «Код» и «Наименование»?
Это стандартные реквизиты, они не входят в коллекцию Реквизиты. Переберите отдельно Метаданные().СтандартныеРеквизиты — там будут Код, Наименование, Ссылка, ПометкаУдаления и другие системные поля, состав которых зависит от настроек объекта.
Как перебрать реквизиты объекта на управляемой форме?
На форме данные обычно представлены как ДанныеФормыСтруктура, у которой нет метода Метаданные(). Варианты: получить метаданные через ссылку объекта (Объект.Ссылка.Метаданные()), либо преобразовать данные формы в объект через РеквизитФормыВЗначение("Объект") и работать с ним. Для чтения значений достаточно первого варианта.
Как узнать тип реквизита при переборе?
У элемента коллекции метаданных есть свойство Тип — это объект ОписаниеТипов. Через него можно проверить, содержит ли реквизит конкретный тип: Реквизит.Тип.СодержитТип(Тип("Строка")). Это полезно при универсальном копировании или фильтрации реквизитов по типу.
Перебираются ли общие реквизиты в этой коллекции?
Да. Общие реквизиты, у которых в свойстве «Состав» данный объект отмечен для использования, входят в коллекцию Метаданные().Реквизиты конкретного объекта. Отдельно обращаться к ветке «Общие реквизиты» конфигурации не требуется.
Что быстрее: перебор по метаданным или прямое обращение по именам?
Для одного объекта разница незаметна. Перебор по метаданным оправдан, когда состав реквизитов заранее неизвестен или обработка должна работать с разными видами объектов. Если структура известна и нужна максимальная скорость на больших объёмах, прямое обращение к конкретным полям или запрос предпочтительнее.
Что важно запомнить
Перебор всех реквизитов объекта в 1С выполняется через метаданные: цикл по Метаданные().Реквизиты плюс чтение значений как Объект[Реквизит.Имя]. Стандартные реквизиты перебираются отдельно, табличные части — вложенным циклом по строкам. Для массовой обработки используйте запросы, а любые обработки с записью сначала проверяйте на копии базы.