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

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

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

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

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

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

Объектная модель справочника: ссылка, объект, менеджер

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

Минимальный код создания нового элемента выглядит так:

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

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

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

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

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

После вызова Записать() у объекта появляется заполненное свойство Ссылка. Если справочник подчинённый (например, «Единицы измерения» подчинены «Номенклатуре»), перед записью обязательно заполните реквизит Владелец, иначе получите ошибку.

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

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

ИскомоеНаименование = "ООО «Ромашка»";

НайденнаяСсылка = Справочники.Контрагенты.НайтиПоНаименованию(ИскомоеНаименование, Истина);

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

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

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

НовыйЭлемент.ИНН = "7701234567";

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

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

Иначе

Результат = НайденнаяСсылка;

КонецЕсли;

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

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

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

Изменение существующего элемента

Чтобы изменить уже записанный элемент, получите его объект по ссылке, измените реквизиты и запишите. Типичный сценарий — обновление цены, артикула или признака у найденного элемента:

ЭлементОбъект = НайденнаяСсылка.ПолучитьОбъект();

ЭлементОбъект.Артикул = "КБ-002";

ЭлементОбъект.Комментарий = "Обновлено загрузкой";

ЭлементОбъект.Записать();

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

Для пометки элемента на удаление программно используйте метод УстановитьПометкуУдаления(Истина) объекта. Полное физическое удаление выполняется только штатной обработкой «Удаление помеченных объектов» — удалять элементы напрямую методом Удалить() не рекомендуется, так как это нарушает ссылочную целостность.

Работа с группами, иерархией и табличными частями

Если справочник иерархический, элементу можно назначить родителя через реквизит Родитель. Сама группа создаётся отдельным методом менеджера:

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

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

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

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

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

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

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

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

Табличные части элемента заполняются как коллекции строк объекта. Каждая строка добавляется методом Добавить():

ЭлементОбъект = СсылкаНоменклатуры.ПолучитьОбъект();

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

НоваяСтрока.Свойство = СвойствоСсылка;

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

ЭлементОбъект.Записать();

Перед заполнением табличной части при повторной загрузке имеет смысл очистить её методом Очистить() или удалить только нужные строки — иначе строки будут накапливаться дублями при каждом запуске обработки.

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

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

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

НовыйЭлемент.Наименование = "Тестовая позиция";

НовыйЭлемент.ОбменДанными.Загрузка = Истина;

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

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

При пакетной записи большого числа элементов оборачивайте цикл в транзакцию (НачатьТранзакцию() / ЗафиксироватьТранзакцию()) или, наоборот, записывайте порциями по 500–1000 элементов с фиксацией — слишком длинная транзакция держит блокировки и мешает другим пользователям. Выбор зависит от требования: либо всё-или-ничего, либо максимальная скорость с частичным прогрессом.

Варианты записи элемента

Обычная запись Записать()

Полная проверка данных и отработка подписок. Подходит для интерактивных обработок и небольших объёмов.

Запись с ОбменДанными.Загрузка = Истина

Быстро, без проверок и событий. Подходит для первичной загрузки проверенных данных, но требует контроля качества вручную.

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

Гарантирует целостность партии данных. Подходит для загрузки связанных элементов, где частичный результат недопустим.

Типичные ошибки и проверка результата

Самая частая ошибка — попытка присвоить значение реквизиту через ссылку: Ссылка.Наименование = "...". Платформа выдаст ошибку «Поле объекта недоступно для записи», потому что ссылка предназначена только для чтения. Всегда получайте объект через ПолучитьОбъект().

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

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

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

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

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

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

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

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

Ссылка пустая — запись не выполнена, ищите исключение

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

Все реквизиты заполнены, элемент в нужной группе

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

Пустые реквизиты или элемент в корне справочника

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

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

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

Больше исходного — созданы дубли, меньше — часть строк не обработана

FAQ: частые вопросы о программной записи справочников

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

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

Как найти элемент по наименованию, если точное написание неизвестно?

Метод НайтиПоНаименованию() с параметром Ложь ищет по началу строки, но это ненадёжно. Лучше использовать запрос с оператором ПОДОБНО и шаблоном "%фрагмент%" — так можно найти элементы по части наименования в любом месте строки.

Можно ли записать элемент без прав на интерактивное изменение?

Программная запись проверяет те же права, что и интерактивная. Если у пользователя нет права «Добавление» или «Изменение» для справочника, Записать() выдаст ошибку нарушения прав доступа. Для служебных обработок используйте УстановитьПривилегированныйРежим(Истина), если это оправдано архитектурой решения.

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

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

Как записать предопределённый элемент программно?

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

Что делать, если Записать() вызывает ошибку блокировки?

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

Итог

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

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