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