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

Справочники и Данные · 13 мин

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

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

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

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

Ниже разобран полный рабочий код, варианты для иерархических и подчинённых справочников, способы проверки на дубли и ограничения, о которых нужно помнить перед запуском обработки на рабочей базе.

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

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

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

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

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

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

Сообщить("Создан элемент: " + НовыйЭлемент.Ссылка);

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

Обратите внимание: присваивание значений реквизитам выполняется напрямую через точку, без каких-либо сеттеров. Если реквизит с указанным именем не существует в конфигурации, платформа выдаст ошибку «Поле объекта не обнаружено» уже на этапе выполнения, поэтому имена реквизитов проверяйте по конфигуратору, а не по подписям на форме.

bsl
НовыйЭлемент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйЭлемент.Наименование = "ООО Ромашка";
НовыйЭлемент.ИНН = "7701234567";
НовыйЭлемент.Записать();
СсылкаНаЭлемент = НовыйЭлемент.Ссылка;

Заполнение стандартных и пользовательских реквизитов

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

Пользовательские реквизиты заполняются по типу. Для реквизита ссылочного типа нужно присвоить именно ссылку на объект, а не строку:

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

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

Если реквизит даты — присваивается значение типа Дата, если булево — Истина или Ложь. Типовая ошибка новичков — присвоить строку туда, где ожидается ссылка: платформа либо выдаст ошибку несоответствия типов, либо молча запишет пустое значение, если реквизит составного типа. Проверяйте тип реквизита в конфигураторе перед написанием кода.

Работа с иерархическими и подчинёнными справочниками

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

Для иерархического справочника (вида иерархии «Список» или «Группы и элементы») элемент помещается в нужную группу через реквизит Родитель. Сначала находят или создают группу, затем присваивают её ссылку:

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

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

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

НоваяГруппа.Наименование = "Кабельная продукция";

НоваяГруппа.Записать();

Группа = НоваяГруппа.Ссылка;

КонецЕсли;

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

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

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

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

Группа создаётся методом СоздатьГруппу(), а не СоздатьЭлемент(). Если попытаться присвоить реквизиту Родитель ссылку на обычный элемент (не группу) в справочнике с иерархией «Группы и элементы», при записи возникнет ошибка. Для справочников с иерархией элементов такого ограничения нет.

Создание подчинённого элемента

У подчинённых справочников (например, «Договоры контрагентов» подчинены «Контрагентам») обязателен реквизит Владелец. Без его заполнения запись либо невозможна, либо элемент окажется «осиротевшим» и не отобразится в стандартных списках, отфильтрованных по владельцу.

Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");

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

Договор.Владелец = Контрагент;

Договор.Наименование = "Договор поставки № 15";

Договор.Записать();

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

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

Существующий = Справочники.Номенклатура.НайтиПоНаименованию("Кабель ВВГ 3х2,5");

Если Существующий.Пустая() Тогда

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

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

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

Иначе

Сообщить("Элемент уже существует: " + Существующий);

КонецЕсли;

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

При поиске по реквизиту метод НайтиПоРеквизиту("ИНН", "7701234567") работает только если реквизит проиндексирован. Для неиндексированных реквизитов используйте запрос — это быстрее и не зависит от настроек индексирования.

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

Запись в транзакции и пакетное создание

При загрузке сотен или тысяч элементов каждую запись стоит выполнять в общей транзакции либо порционно. Транзакция гарантирует, что при сбое в середине загрузки база не останется в полузаполненном состоянии: либо записывается всё, либо ничего.

НачатьТранзакцию();

Попытка

Для Каждого СтрокаДанных Из ДанныеЗагрузки Цикл

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

НовыйЭлемент.Наименование = СтрокаДанных.Наименование;

НовыйЭлемент.Артикул = СтрокаДанных.Артикул;

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

КонецЦикла;

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

Сообщить("Ошибка загрузки: " + ОписаниеОшибки());

КонецПопытки;

Для очень больших объёмов одиночная транзакция может привести к длительным блокировкам таблицы и конфликтам с работой пользователей. В этом случае фиксируйте транзакцию порциями, например каждые 100–500 элементов, и ведите журнал уже загруженных позиций, чтобы при повторном запуске пропускать их.

Метод Записать() имеет необязательный параметр режима загрузки: НовыйЭлемент.ОбменДанными.Загрузка = Истина; перед записью отключает проверки заполнения и бизнес-логику подписок. Это ускоряет массовую загрузку, но опасно: можно записать элементы, нарушающие правила конфигурации. Используйте режим загрузки только при миграции данных из проверенного источника и никогда — в обычных обработчиках.

Права доступа и типичные ошибки

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

Ещё одна группа ошибок связана с контекстом выполнения. В тонком и веб-клиенте создание объектов доступно только на сервере: код с СоздатьЭлемент() должен находиться в серверной процедуре (директива &НаСервере или серверный общий модуль). Попытка выполнить его на клиенте приведёт к ошибке «Метод объекта не обнаружен» или недоступности менеджера справочника.

Также учитывайте, что при записи срабатывают обработчики событий ПередЗаписью, ПриЗаписи и подписки на события, определённые в конфигурации. Если в них есть проверки или обращения к другим объектам, программная запись может завершиться ошибкой даже при корректном коде. Читайте текст исключения: он обычно указывает, из какого обработчика пришёл отказ.

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

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

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

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

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

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

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

Ссылка не пустая, элемент открывается

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

Исключение при записи или пустая ссылка

Отображение в списке справочника
Норма

Элемент виден в нужной группе или у владельца

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

Элемент не отображается — проверьте Родитель/Владелец

Заполненность реквизитов
Норма

Все обязательные поля заполнены корректными типами

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

Пустые или неверные значения — проверьте типы реквизитов

Количество созданных элементов при пакетной загрузке
Норма

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

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

Меньше ожидаемого — ищите ошибки в журнале или пропуски дублей

FAQ: частые вопросы

Чем отличается СоздатьЭлемент() от ПолучитьСсылку()?

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

Как создать элемент с заданным кодом вручную?

Присвойте значение свойству Код до вызова Записать(): НовыйЭлемент.Код = "000123". Учтите, что при включённой автонумерации платформа может перезаписать код при записи, а при контроле уникальности дубль кода вызовет ошибку. Для числовых кодов присваивайте число, для строковых — строку.

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

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

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

Да, одиночный вызов Записать() выполняется в неявной транзакции, которую платформа открывает и фиксирует автоматически. Явная транзакция нужна только при записи нескольких связанных объектов, когда требуется принцип «всё или ничего».

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

Код идентичен: разместите создание элемента в серверной процедуре модуля формы или в модуле объекта обработки. Убедитесь, что у пользователя, запускающего обработку, есть права на добавление элементов этого справочника, иначе запись завершится ошибкой доступа.

Что делать, если элементы создаются, но не видны пользователям?

Проверьте три вещи: не установлена ли пометка удаления, корректно ли заполнены Родитель и Владелец (элемент мог попасть вне видимой ветки), и нет ли в конфигурации ограничения доступа на уровне записей (RLS), скрывающего новые элементы от части пользователей.

Итог

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

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