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