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