К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как программно создать новый элемент справочника в 1С

Как программно создать элемент справочника в 1С: методы СоздатьЭлемент, установка реквизитов, работа с группами, запись и типичные ошибки разработчика.

Программное создание элемента справочника — одна из базовых операций при разработке на платформе 1С:Предприятие. Она используется при обмене данными, загрузке номенклатуры из файлов, автоматическом заполнении справочников по данным документов и в десятках других сценариев интеграции и автоматизации.

Основной инструмент — метод СоздатьЭлемент() менеджера справочника. Он создаёт новый объект в памяти, не записывая его в базу данных. Запись происходит только после вызова метода Записать(), и до этого момента у элемента нет ссылки, а база данных не изменена. Понимание этого разделения критично: многие ошибки новичков связаны именно с попыткой использовать ссылку до записи объекта.

Ниже разобран полный цикл: от минимального кода до работы с группами, табличными частями, проверки дублей и различий между обычным и управляемым приложением. Примеры приведены на встроенном языке 1С и подходят для версий платформы 8.3.

Минимальный код создания элемента справочника

Простейший сценарий состоит из трёх шагов: создать объект, заполнить реквизиты, записать. Для справочника «Номенклатура» код выглядит так:

НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

НовыйЭлемент.Наименование = "Кабель ВВГ 3х2,5";

НовыйЭлемент.Артикул = "КБ-001";

НовыйЭлемент.Записать();

После выполнения Записать() переменная НовыйЭлемент.Ссылка содержит ссылку на созданный элемент, которую можно использовать в других объектах — например, подставить в реквизит документа. До вызова Записать() свойство Ссылка возвращает пустую ссылку, и попытка записать её куда-либо приведёт к ошибочным данным.

Обратите внимание: если у справочника включена автонумерация, код присваивается автоматически при записи. Если автонумерация отключена, код нужно установить вручную через свойство Код, иначе платформа может выдать ошибку о неуникальности (при контроле уникальности кода).

Заполнение реквизитов и проверка обязательных полей

Реквизиты элемента заполняются через точечное обращение по имени, как оно задано в конфигураторе. Тип значения должен соответствовать типу реквизита: строке — строка, числу — число, ссылочному реквизиту — ссылка на объект другого справочника или документа.

НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

НовыйЭлемент.Наименование = "Кабель ВВГ 3х2,5";

НовыйЭлемент.ЕдиницаИзмерения = Справочники.ЕдиницыИзмерения.НайтиПоНаименованию("м");

НовыйЭлемент.СтавкаНДС = Перечисления.СтавкиНДС.НДС20;

НовыйЭлемент.Записать();

Частая ошибка — присваивание ссылочному реквизиту строки вместо ссылки. Платформа в этом случае либо выдаст ошибку несоответствия типов, либо, если реквизит составного типа, запишет строку, что впоследствии сломает отчёты и запросы. Всегда получайте ссылку через НайтиПоНаименованию(), НайтиПоКоду() или создавайте связанный объект программно.

Если реквизит помечен в конфигураторе как обязательный (проверка заполнения — «Выдавать ошибку»), метод Записать() завершится исключением при пустом значении. Перед записью можно программно проверить заполнение методом ПроверитьЗаполнение() — он вернёт Ложь и выведет сообщения о незаполненных полях, не прерывая выполнение исключением.

bsl
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Кабель ВВГ 3х2,5";
Если НовыйЭлемент.ПроверитьЗаполнение() Тогда
    НовыйЭлемент.Записать();
Иначе
    Сообщить("Элемент не записан: заполнены не все обязательные поля");
КонецЕсли;

Создание элемента внутри группы и работа с иерархией

Для иерархических справочников (с иерархией элементов или групп и элементов) новый элемент можно поместить в нужную группу через реквизит Родитель. Родителем должна быть ссылка на группу, а не на обычный элемент.

Группа = Справочники.Номенклатура.НайтиПоНаименованию("Кабельная продукция");

Если Не Группа.Пустая() Тогда

НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

НовыйЭлемент.Наименование = "Кабель ВВГ 3х2,5";

НовыйЭлемент.Родитель = Группа;

НовыйЭлемент.Записать();

КонецЕсли;

Если нужной группы ещё нет, её создают методом СоздатьГруппу() вместо СоздатьЭлемент(). У группы обычно заполняют только наименование — реквизиты, предназначенные для элементов, у групп недоступны или игнорируются.

При поиске родителя по наименованию учитывайте, что НайтиПоНаименованию() ищет точное совпадение и может вернуть элемент, а не группу, если наименования совпадают. Для надёжности используйте третий параметр метода (родитель) и проверяйте, что найденный объект — группа: в запросе это можно сделать через поле ЭтоГруппа.

Заполнение табличных частей и дополнительных данных

Если у справочника есть табличные части (например, «ДополнительныеРеквизиты» в типовых конфигурациях), они заполняются до записи элемента. Каждая строка добавляется методом Добавить() коллекции табличной части:

НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

НовыйЭлемент.Наименование = "Кабель ВВГ 3х2,5";

НоваяСтрока = НовыйЭлемент.ДополнительныеРеквизиты.Добавить();

НоваяСтрока.Свойство = СвойствоЦвет;

НоваяСтрока.Значение = "Чёрный";

НовыйЭлемент.Записать();

Вся табличная часть сохраняется одним вызовом Записать() вместе с шапкой объекта — отдельно записывать строки не нужно. Это гарантирует целостность: либо записан весь объект целиком, либо ничего.

Для подчинённых справочников (например, «Единицы измерения», подчинённые «Номенклатуре») у нового элемента обязательно заполняется реквизит Владелец — ссылка на элемент справочника-владельца. Владелец должен быть уже записан в базу: ссылка на несохранённый объект не сработает.

Порядок действий
  1. 1
    Получите менеджер справочника: Справочники.ИмяСправочника
  2. 2
    Вызовите СоздатьЭлемент() — объект создан в памяти
  3. 3
    Заполните Наименование, Код (если нет автонумерации) и реквизиты
  4. 4
    Для иерархического справочника установите Родитель, для подчинённого — Владелец
  5. 5
    Добавьте строки табличных частей через Добавить()
  6. 6
    Вызовите ПроверитьЗаполнение() для контроля обязательных полей
  7. 7
    Вызовите Записать() и проверьте, что Ссылка заполнена

Проверка на дубли перед созданием

При загрузке данных из внешних источников создавать элемент «вслепую» опасно: справочник быстро заполняется дублями, которые потом приходится разбирать вручную, а ссылки на дубли уже могут попасть в документы. Стандартная практика — сначала искать существующий элемент по ключевому признаку.

Ссылка = Справочники.Номенклатура.НайтиПоНаименованию(НаименованиеИзФайла, Истина);

Если Ссылка.Пустая() Тогда

НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

НовыйЭлемент.Наименование = НаименованиеИзФайла;

НовыйЭлемент.Записать();

Ссылка = НовыйЭлемент.Ссылка;

КонецЕсли;

Выбор ключа поиска зависит от данных: наименование подходит, только если оно гарантированно уникально и стабильно. Надёжнее искать по артикулу, ИНН, штрихкоду или внешнему идентификатору из системы-источника — для этого часто добавляют отдельный реквизит с индексированием. Поиск по индексированному реквизиту работает на порядки быстрее, что критично при пакетной загрузке тысяч позиций.

Для массовых загрузок полезен приём «найти или создать»: единая функция, которая принимает параметры элемента и возвращает ссылку — существующую или вновь созданную. Это избавляет от дублирования логики поиска по всему коду обмена.

Типичные ошибки
01
Использование ссылки до Записать() — в реквизиты других объектов попадает пустая ссылка
02
Присвоение ссылочному реквизиту строки вместо ссылки — ошибка типов или мусорные данные
03
Создание дублей при загрузке без предварительного поиска по ключевому реквизиту
04
Попытка установить Родителем обычный элемент в справочнике с иерархией групп — ошибка при записи
05
Игнорирование обязательных реквизитов — исключение при Записать() без понятного контекста
06
Создание элемента в цикле с записью по одному без транзакции — медленно и риск частичной загрузки

Особенности: транзакции, обмен данными и права

При создании нескольких связанных элементов (например, номенклатуры и её единиц измерения) оборачивайте операции в транзакцию через НачатьТранзакцию() и ЗафиксироватьТранзакцию(). Тогда при ошибке на середине пакета база не останется в рассогласованном состоянии — ОтменитьТранзакцию() откатит все записи.

Если элемент создаётся в рамках обмена данными и не должен регистрироваться к выгрузке в другие узлы, перед записью установите НовыйЭлемент.ОбменДанными.Загрузка = Истина. Этот режим также отключает большинство проверок заполнения и обработчиков — используйте его осознанно, только когда данные гарантированно корректны, иначе в базе окажутся незаполненные или противоречивые элементы.

У пользователя, от имени которого выполняется код, должны быть права на добавление элементов справочника. В файловой базе под полными правами это не проблема, но во внешних обработках, регламентных заданиях и веб-сервисах код может выполняться под ограниченной учётной записью — тогда Записать() выдаст ошибку нарушения прав доступа. Для серверного кода в привилегированном модуле проверка прав отключается, что тоже нужно учитывать при проектировании безопасности.

Проверка результата и отладка

После записи убедитесь, что элемент действительно создан: проверьте, что НовыйЭлемент.Ссылка.Пустая() возвращает Ложь. Дополнительно можно перечитать объект из базы через Ссылка.ПолучитьОбъект() и сверить значения реквизитов — это исключает ситуацию, когда обработчики «ПриЗаписи» в конфигурации изменили данные.

Для отладки удобно выводить созданные ссылки в журнал через Сообщить() или записывать в журнал регистрации. При массовой загрузке считайте итоговые счётчики: сколько создано, сколько найдено существующих, сколько пропущено с ошибками. Расхождение этих цифр с количеством строк источника — первый признак проблем в логике.

Контрольные точки

Как проверить результат

Ссылка после Записать()
Норма

Ссылка заполнена, Пустая() возвращает Ложь

Тревожный признак

Ссылка пустая — запись не выполнена, смотрите сообщения об ошибках

Элемент в списке справочника
Норма

Элемент виден в нужной группе с корректными реквизитами

Тревожный признак

Элемент в корне списка или с пустыми полями — ошибка в заполнении Родителя или реквизитов

Количество созданных элементов
Норма

Совпадает с числом новых строк источника

Тревожный признак

Больше ожидаемого — дубли, меньше — часть строк пропущена с ошибками

Частые вопросы

Чем отличается СоздатьЭлемент() от СоздатьГруппу()?

СоздатьЭлемент() создаёт обычный элемент справочника, СоздатьГруппу() — группу для иерархического справочника. Группа служит папкой для элементов и других групп, у неё недоступны реквизиты, предназначенные только для элементов. Оба объекта записываются методом Записать().

Как создать элемент, не регистрируя его для обмена данными?

Перед записью установите свойство НовыйЭлемент.ОбменДанными.Загрузка = Истина. Запись пройдёт без регистрации изменений в планах обмена и без срабатывания большинства проверок. Применяйте режим только для заведомо корректных данных — отключённые проверки не защитят от ошибок.

Можно ли задать код элемента вручную?

Да, через свойство Код, если в конфигураторе для справочника отключена автонумерация. При включённой автонумерации платформа присвоит код сама при записи, а ручное значение может быть проигнорировано или вызвать конфликт уникальности. Узнать настройку можно в свойствах справочника в конфигураторе.

Почему Записать() выдаёт ошибку «Ошибка при вызове метода контекста»?

Чаще всего причина в незаполненных обязательных реквизитах, нарушении уникальности кода, попытке установить родителем элемент вместо группы или отсутствии прав на добавление. Текст исключения содержит детали — читайте его полностью. Предварительный вызов ПроверитьЗаполнение() помогает локализовать проблему до записи.

Как создать элемент справочника на клиенте в управляемом приложении?

Методы СоздатьЭлемент() и Записать() недоступны на тонком клиенте — они выполняются только на сервере. Создайте серверную процедуру в общем модуле с флагом «Сервер» или в модуле формы с директивой &НаСервере и вызывайте её из клиентского кода, передавая нужные параметры.

Как ускорить создание большого количества элементов?

Используйте поиск дублей по индексированным реквизитам, оборачивайте пакет в одну транзакцию разумного размера, при загрузке из надёжного источника применяйте ОбменДанными.Загрузка = Истина для отключения лишних проверок. Избегайте в цикле вызовов, выполняющих запросы к базе без необходимости.

Итог

Что важно запомнить

Элемент справочника создаётся связкой СоздатьЭлемент() → заполнение реквизитов → Записать(). Ссылка появляется только после записи. Перед созданием ищите дубли по ключевому реквизиту, для иерархии заполняйте Родитель, для подчинённых справочников — Владелец. Массовую загрузку тестируйте на копии базы и выполняйте в транзакции.