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