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