Разработка и Конфигурация · 12 мин
Как создать справочник в 1С программно
Как программно создать справочник в 1С: работа с менеджером справочника, создание элементов и групп, заполнение реквизитов, типовые ошибки и примеры кода.
Программное создание элементов справочников — одна из самых частых задач при разработке и доработке конфигураций 1С. Она возникает при загрузке данных из файлов, синхронизации с внешними системами, первоначальном заполнении базы и в обработчиках событий документов. Встроенный язык 1С предоставляет для этого понятный объектный интерфейс, но у него есть особенности, о которых нужно знать заранее.
Работа ведётся через менеджер справочника — объект вида Справочники.ИмяСправочника. Через него создаются новые элементы и группы, выполняется поиск существующих значений и проверяются дубли. Ключевые методы — СоздатьЭлемент(), СоздатьГруппу(), НайтиПоНаименованию() и НайтиПоКоду().
Важно понимать разницу между созданием объекта в памяти и его записью в базу данных. Новый элемент существует только в оперативной памяти до вызова метода Записать(). Если метод не вызван или запись завершилась ошибкой, данные в информационную базу не попадут — это одна из самых распространённых причин «потерянных» элементов у начинающих разработчиков.
Объектная модель работы со справочниками
Доступ к любому справочнику конфигурации осуществляется через глобальное свойство Справочники. Обращение вида Справочники.Контрагенты возвращает менеджер справочника, через который выполняются все операции: создание, поиск, получение объекта по ссылке, выборка элементов.
Менеджер возвращает два типа объектов. СправочникОбъект — полноценный объект с возможностью изменения и записи, его возвращают методы СоздатьЭлемент(), СоздатьГруппу() и ПолучитьОбъект() у ссылки. СправочникСсылка — лёгкий объект-указатель на существующий элемент, пригодный только для чтения данных и сравнения.
Это разделение важно для производительности: если нужно только прочитать наименование или реквизит, достаточно ссылки — обращение через точку (например, Ссылка.Наименование) выполняется запросом к базе без загрузки всего объекта. Получать объект через ПолучитьОбъект() следует только тогда, когда планируется изменение данных.
Базовый сценарий: создание простого элемента
Минимальный код создания элемента выглядит так: получаем менеджер, вызываем СоздатьЭлемент(), заполняем реквизиты, записываем. После успешной записи у объекта появляется ссылка, которую можно использовать для связи с другими объектами.
НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.Наименование = "ООО Ромашка";
НовыйКонтрагент.ИНН = "7712345678";
НовыйКонтрагент.Записать();
СсылкаНаКонтрагента = НовыйКонтрагент.Ссылка;
Обратите внимание: присваивать значения можно только реквизитам, реально существующим в конфигурации. Обращение к несуществующему реквизиту вызовет ошибку времени выполнения. Если код пишется универсально и состав реквизитов заранее неизвестен, используйте метаданные для проверки.
После вызова Записать() платформа выполняет проверку заполнения обязательных реквизитов, контроль уникальности кода (если он включён в свойствах справочника) и обработчики событий ПередЗаписью и ПриЗаписи. Ошибка на любом из этих этапов прерывает запись и вызывает исключение.
- 1Получите менеджер: Справочники.ИмяСправочника
- 2Вызовите СоздатьЭлемент() или СоздатьГруппу()
- 3Заполните наименование и обязательные реквизиты
- 4При необходимости укажите родителя и владельца
- 5Вызовите Записать() и обработайте возможное исключение
- 6Проверьте результат через Ссылка и поиск в базе
Создание групп и работа с иерархией
Если справочник иерархический, элементы можно распределять по папкам. Группа создаётся методом СоздатьГруппу(), а привязка элемента к группе выполняется через реквизит Родитель, которому присваивается ссылка на группу.
Группа = Справочники.Номенклатура.СоздатьГруппу();
Группа.Наименование = "Материалы";
Группа.Записать();
Товар = Справочники.Номенклатура.СоздатьЭлемент();
Товар.Наименование = "Краска белая";
Товар.Родитель = Группа.Ссылка;
Товар.Записать();
Вид иерархии задаётся в конфигураторе и влияет на логику кода. При иерархии «список групп и элементов» элемент можно поместить в любую группу. При иерархии «элементов» родителем может быть другой элемент. Попытка присвоить родителя неподходящего вида приведёт к ошибке при записи.
Нельзя записать элемент, ссылающийся на ещё не записанную группу: у незаписанного объекта нет ссылки. Поэтому порядок строго определён — сначала Записать() для группы, затем создание дочерних элементов. При загрузке многоуровневой иерархии из файла группы записывают по уровням, от корня к листьям.
Проверка дублей перед созданием
Создание элемента без проверки существования — типичный источник задвоенной номенклатуры и контрагентов. Перед созданием следует искать элемент по ключевым признакам: коду, наименованию или естественному ключу (ИНН для контрагентов, артикулу для товаров).
ИскомыйИНН = "7712345678";
Найденный = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", ИскомыйИНН);
Если Найденный.Пустая() Тогда
Новый = Справочники.Контрагенты.СоздатьЭлемент();
Новый.Наименование = "ООО Ромашка";
Новый.ИНН = ИскомыйИНН;
Новый.Записать();
Иначе
Сообщить("Контрагент уже существует: " + Найденный.Наименование);
КонецЕсли;
Методы поиска: НайтиПоНаименованию(Наименование, ТочноеСоответствие), НайтиПоКоду(Код), НайтиПоРеквизиту(ИмяРеквизита, Значение). Все они возвращают ссылку; если ничего не найдено — пустую ссылку, которую проверяют методом Пустая(). Учтите, что поиск по наименованию без флага точного соответствия ищет по началу строки.
Подчинённые справочники, табличные части и дополнительные реквизиты
Если справочник подчинён другому (например, «Договоры контрагентов» подчинены «Контрагентам»), при создании обязательно указывается реквизит Владелец. Без него запись будет невозможна или элемент окажется недоступен в интерфейсе владельца.
Договор = Справочники.ДоговорыКонтрагентов.СоздатьЭлемент();
Договор.Владелец = СсылкаНаКонтрагента;
Договор.Наименование = "Договор поставки № 15";
Договор.Записать();
Табличные части заполняются добавлением строк: НовыйЭлемент.Товары.Добавить() возвращает строку, реквизиты которой заполняются обычным присваиванием. Табличная часть сохраняется вместе с объектом при вызове Записать() — отдельной записи она не требует.
В типовых конфигурациях на платформе 8.3 значительная часть свойств хранится не в реквизитах, а в механизме дополнительных реквизитов и сведений (БСП). Простое присваивание Объект.Цвет = ... для такого свойства вызовет ошибку — значения записываются через табличную часть ДополнительныеРеквизиты с указанием ссылки на свойство из плана видов характеристик.
Массовое создание: транзакции и производительность
При загрузке сотен и тысяч элементов каждая запись по умолчанию выполняется в отдельной транзакции, что заметно замедляет процесс. Объединение операций в одну транзакцию через НачатьТранзакцию() и ЗафиксироватьТранзакцию() ускоряет загрузку и гарантирует целостность: при ошибке вся пачка откатывается.
НачатьТранзакцию();
Попытка
Для Каждого СтрокаДанных Из ДанныеЗагрузки Цикл
Элемент = Справочники.Номенклатура.СоздатьЭлемент();
Элемент.Наименование = СтрокаДанных.Наименование;
Элемент.Записать();
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
У монолитной транзакции есть обратная сторона: сбой на последнем элементе отменит всю загрузку. Альтернатива — порционная фиксация, например каждые 500–1000 элементов. Такой подход сочетает приемлемую скорость с умеренными потерями при ошибке.
Дополнительные приёмы ускорения: отключить использование итогов там, где это применимо, загружать данные порциями через запросы вместо построчного чтения, а при обмене использовать ОбменДанными.Загрузка = Истина — этот режим отключает проверки и обработчики записи. Применять его стоит осознанно: отключается и контроль корректности данных.
Способы записи при загрузке
Просто и надёжно, ошибка затрагивает один элемент. Медленно при больших объёмах.
Максимальная скорость и целостность, но сбой откатывает всё и держит блокировки дольше.
Компромисс: фиксация каждые несколько сотен элементов, потеря ограничена одной порцией.
Быстрее за счёт отключения проверок, но ответственность за корректность данных ложится на код загрузки.
Проверка результата и отладка
После выполнения кода убедитесь, что элементы реально появились в базе. Простейший способ — открыть список справочника в режиме предприятия. Программно проверку делают поиском по созданному значению или запросом с подсчётом количества.
Полезные приёмы отладки: вывод созданной ссылки через Сообщить(), проверка НовыйЭлемент.ЭтоНовый() до записи (должно быть Истина), анализ текста исключения — платформа обычно указывает, какой реквизит не заполнен или какое правило нарушено. В конфигураторе удобно поставить точку останова на строке Записать() и посмотреть состояние объекта в табло.
Как проверить результат
Новая строка видна в режиме предприятия с корректным наименованием
Элемента нет — вероятно, не вызван Записать() или произошло исключение
Свойство Ссылка заполнено, ЭтоНовый() возвращает Ложь
Ссылка пустая — запись не выполнена
Элемент отображается внутри нужной группы
Элемент в корне списка — не заполнен Родитель или группа не была записана
Поиск по ключу находит ровно один элемент
Несколько одинаковых записей — отсутствовала проверка перед созданием
Частые вопросы
Чем отличается СоздатьЭлемент() от ПолучитьОбъект()?
СоздатьЭлемент() создаёт новый объект в памяти, которого ещё нет в базе. ПолучитьОбъект() вызывается у существующей ссылки и загружает из базы уже записанный элемент для изменения. Первый используют для добавления данных, второй — для редактирования.
Как создать элемент справочника в фоновом задании?
Код создания тот же, но в фоновом задании недоступен интерактивный интерфейс: нельзя открывать формы и показывать диалоги. Сообщения пользователю заменяют записью в журнал регистрации или передачей результата через параметры фонового задания.
Можно ли задать код элемента вручную?
Да, свойству Код можно присвоить значение до записи, если в конфигураторе для справочника включён ручной ввод кодов. При автонумерации платформа присвоит код сама, а ручная установка может нарушить последовательность нумерации.
Что делать, если Записать() вызывает ошибку в типовой конфигурации?
Читайте текст исключения: чаще всего не заполнен обязательный реквизит или срабатывает проверка в обработчике ПередЗаписью. Полезно создать аналогичный элемент вручную в режиме предприятия и посмотреть, какие поля конфигурация заполняет автоматически — их нужно воспроизвести в коде.
Как создать элемент, если справочник вводится на основании другого объекта?
Справочники редко вводятся на основании, но если механизм настроен, используйте метод Заполнить(ДанныеЗаполнения) после СоздатьЭлемент(): объект сам заполнит реквизиты по данным основания через обработчик ОбработкаЗаполнения.
Почему поиск НайтиПоНаименованию не находит существующий элемент?
Наиболее вероятные причины: лишние пробелы или разный регистр не влияют, но поиск без второго параметра Истина ищет по началу наименования, а не по полному совпадению. Также проверьте, не помечен ли элемент на удаление — по умолчанию такие элементы тоже находятся, но логика вашего кода может их отфильтровывать.
Что важно запомнить
Элемент справочника создаётся цепочкой: СоздатьЭлемент() → заполнение реквизитов (включая Родителя и Владельца) → Записать(). Перед созданием проверяйте дубли по уникальному ключу, при массовой загрузке используйте транзакции, а результат всегда проверяйте через ссылку и поиск в базе.