Разработка и Конфигурация · 14 мин
Как добавить данные в справочник 1С программно
Как программно добавить данные в справочник 1С: создание элементов и групп, заполнение реквизитов, поиск дублей, запись через обмен данными. Примеры кода на встроенном языке.
Программное добавление элементов в справочник — одна из самых частых задач при разработке и сопровождении конфигураций 1С. Она возникает при загрузке номенклатуры из файлов, синхронизации с внешними системами, первоначальном заполнении базы и в обработках массового изменения данных. Встроенный язык 1С предоставляет для этого объектную модель: менеджер справочника, объект элемента и метод записи.
Базовый сценарий выглядит одинаково для любого справочника: получить менеджер, создать новый элемент, заполнить реквизиты, вызвать метод Записать(). Однако на практике важны нюансы — контроль дублей, заполнение обязательных полей, работа с иерархией, табличными частями и режимом обмена данными. Игнорирование этих моментов приводит к ошибкам записи, дублям элементов и нарушению целостности данных.
Материал ориентирован на управляемые формы и платформу 8.3, но описанные приёмы применимы и в обычных формах 8.2. Все примеры кода выполняются на сервере; при вызове из клиентского контекста потребуется директива &НаСервере или серверная процедура в общем модуле.
Базовый способ: создание и запись элемента
Минимальный код добавления элемента состоит из трёх шагов. Сначала через менеджер справочника вызывается метод СоздатьЭлемент(), который возвращает объект нового элемента в памяти — в базе данных на этом этапе ничего не появляется. Затем заполняются реквизиты, включая обязательное для большинства справочников поле Наименование. В конце вызывается Записать(), и только после успешного выполнения этого метода элемент фиксируется в базе.
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Кабель ВВГнг 3х2,5";
НовыйЭлемент.Артикул = "КБ-001";
НовыйЭлемент.ЕдиницаИзмерения = Справочники.ЕдиницыИзмерения.НайтиПоКоду("006");
НовыйЭлемент.Записать();
Сообщить("Создан элемент: " + НовыйЭлемент.Ссылка);
Реквизиты ссылочного типа заполняются не строками, а ссылками на элементы других справочников или документов. Если передать строку вместо ссылки, платформа выдаст ошибку несоответствия типов. Поэтому ссылку сначала ищут через НайтиПоКоду(), НайтиПоНаименованию() или получают из параметров обработки.
Если справочник подчинён владельцу (например, «Договоры контрагентов» подчинены «Контрагентам»), обязательно заполняется реквизит Владелец. Без него запись завершится ошибкой, так как платформа контролирует заполненность владельца автоматически.
Создание групп и работа с иерархией
Для иерархических справочников группы создаются отдельным методом СоздатьГруппу(). Группа отличается от элемента признаком ЭтоГруппа, у неё недоступны реквизиты элемента — заполняется только наименование и родитель. Попытка записать группу с заполненными реквизитами элемента приведёт к ошибке.
НоваяГруппа = Справочники.Номенклатура.СоздатьГруппу();
НоваяГруппа.Наименование = "Кабельная продукция";
НоваяГруппа.Записать();
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Провод ПВС 2х0,75";
НовыйЭлемент.Родитель = НоваяГруппа.Ссылка;
НовыйЭлемент.Записать();
Привязка элемента к группе выполняется через реквизит Родитель, которому присваивается ссылка на группу. Если родитель не указан, элемент попадёт в корень справочника. В справочниках с иерархией групп и элементов элемент может находиться в любой группе, а в справочниках с иерархией элементов родителем может быть другой элемент — это задаётся в конфигураторе и влияет на логику обработки.
При массовой загрузке с вложенной структурой удобно сначала создать все группы, сохранив соответствие «имя группы — ссылка» в структуре или соответствии, а затем создавать элементы, подставляя родителя из этого соответствия. Это избавляет от повторных поисков в базе.
Проверка дублей перед добавлением
Повторное создание уже существующего элемента — самая частая причина засорения справочников. Перед созданием следует искать элемент по ключевым полям: наименованию, коду, артикулу, ИНН или другому уникальному реквизиту. Методы поиска возвращают ссылку; если элемент не найден, результат равен пустой ссылке, что проверяется методом Пустая().
НайденнаяСсылка = Справочники.Номенклатура.НайтиПоНаименованию("Кабель ВВГнг 3х2,5", Истина);
Если НайденнаяСсылка.Пустая() Тогда
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Кабель ВВГнг 3х2,5";
НовыйЭлемент.Записать();
Иначе
Сообщить("Элемент уже существует: " + НайденнаяСсылка);
КонецЕсли;
Второй параметр НайтиПоНаименованию определяет точное или неточное совпадение: Истина — точное соответствие строки, Ложь — поиск по началу наименования. Для контроля дублей всегда используйте точное совпадение, иначе «Кабель» и «Кабель ВВГнг» могут быть ошибочно приняты за один элемент.
Если уникальность определяется комбинацией полей (например, ИНН + КПП контрагента), одного метода поиска недостаточно — используйте запрос с отбором по нескольким реквизитам. Это также быстрее при массовой обработке: один запрос по всей пачке загружаемых данных работает заметно эффективнее тысячи вызовов НайтиПоРеквизиту в цикле.
Заполнение табличных частей и дополнительных реквизитов
Табличные части элемента заполняются после создания объекта, но до вызова Записать(). Каждая строка добавляется методом Добавить() табличной части, после чего заполняются её реквизиты. Все строки сохраняются одной операцией записи вместе с шапкой элемента.
НовыйЭлемент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйЭлемент.Наименование = "ООО Ромашка";
НоваяСтрока = НовыйЭлемент.КонтактнаяИнформация.Добавить();
НоваяСтрока.Тип = Перечисления.ТипыКонтактнойИнформации.Адрес;
НоваяСтрока.Представление = "г. Москва, ул. Примерная, д. 1";
НовыйЭлемент.Записать();
В типовых конфигурациях значительная часть данных хранится не в реквизитах справочника, а в дополнительных реквизитах и сведениях — механизм БСП (Библиотека стандартных подсистем). Дополнительные реквизиты физически находятся в табличной части «ДополнительныеРеквизиты», где каждая строка содержит ссылку на свойство (элемент плана видов характеристик «ДополнительныеРеквизитыИСведения») и значение. Дополнительные сведения записываются уже не в объект элемента, а в одноимённый регистр сведений отдельной записью.
При работе с дополнительными реквизитами сначала найдите само свойство по имени или заголовку через запрос к плану видов характеристик, затем добавьте строку в табличную часть с найденной ссылкой. Записывать значение «по имени свойства» напрямую нельзя — платформа работает только со ссылками.
Загрузка из внешних источников: ссылки и режим обмена данными
При синхронизации с внешними системами недостаточно просто создать элемент — нужно сохранить связь между записью во внешней системе и элементом 1С. Для этого используется метод УстановитьСсылкуНового(): новому элементу заранее назначается ссылка, сформированная из уникального идентификатора внешней системы. При повторной загрузке элемент находится по этому идентификатору через ПолучитьСсылку(Новый УникальныйИдентификатор(ГУИД)) и обновляется вместо создания дубля.
Идентификатор = Новый УникальныйИдентификатор(СтрокаГУИДИзФайла);
СсылкаЭлемента = Справочники.Номенклатура.ПолучитьСсылку(Идентификатор);
Если СсылкаЭлемента.ПолучитьОбъект() = Неопределено Тогда
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.УстановитьСсылкуНового(СсылкаЭлемента);
Иначе
НовыйЭлемент = СсылкаЭлемента.ПолучитьОбъект();
КонецЕсли;
НовыйЭлемент.Наименование = НаименованиеИзФайла;
НовыйЭлемент.Записать();
Отдельный приём — запись в режиме обмена данными: НовыйЭлемент.ОбменДанными.Загрузка = Истина. В этом режиме платформа пропускает проверки заполненности и часть обработчиков событий. Это ускоряет массовую загрузку, но перекладывает ответственность за корректность данных на разработчика: обязательные реквизиты могут остаться пустыми, а подписки на события — не выполниться. Используйте режим только в обработках начальной загрузки или синхронизации, где состав данных контролируется кодом.
Сравнение вариантов записи
Выполняются все проверки заполнения и обработчики событий. Подходит для интерактивных обработок и случаев, когда важна бизнес-логика конфигурации. Медленнее при массовой загрузке.
Проверки и часть событий пропускаются, скорость выше. Подходит для синхронизации и начального заполнения, но требует контроля корректности данных в коде.
Сначала запросом определяются отсутствующие элементы, затем создаются только они. Оптимально при загрузке больших объёмов с контролем дублей.
Транзакции и производительность при массовом добавлении
При загрузке сотен и тысяч элементов каждая запись по умолчанию выполняется в собственной неявной транзакции. Явное управление транзакцией решает две задачи: либо гарантирует целостность (все элементы загружены или ни одного), либо ускоряет процесс, если транзакция фиксируется порциями. Полная загрузка в одной транзакции рискованна: при обрыве на последнем элементе откатятся все изменения, а длинные транзакции блокируют работу пользователей.
НачатьТранзакцию();
Попытка
Для Каждого СтрокаДанных Из ДанныеЗагрузки Цикл
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = СтрокаДанных.Наименование;
НовыйЭлемент.Записать();
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
Компромиссный вариант — фиксация порциями по 100–500 элементов. Тогда при сбое теряется только текущая порция, а блокировки не затягиваются. Дополнительно ускоряет загрузку предварительное чтение всех связанных ссылок (единиц измерения, групп, ставок НДС) в соответствие одним запросом вместо поиска в цикле.
- 1Сделайте копию базы и отладьте обработку на ней
- 2Загрузите файл в таблицу значений и проверьте корректность данных
- 3Одним запросом найдите существующие элементы по ключевым полям
- 4Создайте недостающие элементы, заполнив реквизиты и табличные части
- 5Зафиксируйте транзакции порциями, при ошибке — откат и протокол
- 6Проверьте результат: количество созданных элементов, отсутствие дублей и пустых обязательных реквизитов
Проверка результата и типичные проблемы
После выполнения обработки убедитесь, что элементы действительно появились и корректны. Простейшая проверка — открыть справочник в режиме предприятия и отфильтровать по созданной группе или наименованию. Для массовой загрузки надёжнее программная проверка запросом: количество элементов с заданным признаком, отсутствие пустых обязательных реквизитов, отсутствие дублей по ключевым полям.
Характерная проблема — «битые ссылки» после некорректной загрузки: элемент создан, но его реквизиты ссылаются на несуществующие объекты. Такое случается, если связанные справочники загружались в неправильном порядке. Правильная последовательность — сначала независимые справочники (валюты, единицы измерения), затем зависимые (номенклатура, контрагенты), затем подчинённые (договоры, банковские счета).
Ещё один признак проблемы — элементы видны в списке, но не открываются или открываются с ошибкой. Обычно причина в незаполненных служебных реквизитах типовой конфигурации, которые записываются обработчиками при интерактивном создании, но пропускаются при записи в режиме обмена данными. Решение — либо заполнять эти реквизиты явно, либо отказаться от режима загрузки для данного справочника.
Как проверить результат
Созданные позиции отображаются, открываются без ошибок, реквизиты заполнены
Элементы отсутствуют, не открываются или открываются с пустыми полями
Запрос по наименованию или артикулу возвращает по одному элементу
Несколько элементов с одинаковым наименованием или кодом
Реквизиты ссылаются на существующие объекты, отчёты по справочнику строятся без ошибок
В реквизитах битые ссылки вида «Объект не найден»
Часто задаваемые вопросы
Как добавить элемент в подчинённый справочник?
Заполните реквизит Владелец ссылкой на элемент справочника-владельца до вызова Записать(). Например, для договора контрагента владельцем будет ссылка на контрагента. Без владельца запись завершится ошибкой — платформа контролирует его заполненность автоматически.
Чем отличается СоздатьЭлемент() от ПолучитьСсылку()?
СоздатьЭлемент() создаёт новый объект в памяти для последующей записи. ПолучитьСсылку() формирует ссылку с заданным или новым идентификатором, не обращаясь к данным, — она используется для проверки существования элемента и назначения ссылки новому объекту через УстановитьСсылкуНового.
Почему запись завершается ошибкой «Поле не может быть пустым»?
В конфигурации для реквизита установлена проверка заполнения. Найдите в конфигураторе список обязательных реквизитов справочника и заполняйте их все перед Записать(). Альтернатива — запись с ОбменДанными.Загрузка = Истина, но тогда ответственность за полноту данных лежит на вашем коде.
Как обновить существующий элемент вместо создания нового?
Получите объект по ссылке: ОбъектЭлемента = СсылкаНаЭлемент.ПолучитьОбъект(), измените нужные реквизиты и вызовите Записать(). Предварительно элемент находят через НайтиПоНаименованию, НайтиПоРеквизиту или по сохранённому уникальному идентификатору.
Можно ли добавлять элементы справочника через COM-соединение из другой базы?
Да, через V83.COMConnector устанавливается соединение с информационной базой, после чего в ней доступен тот же объектный интерфейс: Соединение.Справочники.Имя.СоздатьЭлемент(). Учитывайте, что COM-соединение требует соответствующих прав и работает медленнее прямого доступа.
Как отменить ошибочно загруженные элементы?
Если загрузка шла в одной транзакции — откатите её до фиксации. Если данные уже записаны, используйте пометку удаления по отбору (например, по комментарию или дате создания) с последующим штатным удалением помеченных объектов. Восстановление базы из копии, сделанной до загрузки, — самый надёжный вариант при массовой ошибке.
Что важно запомнить
Добавление элемента справочника — это цепочка СоздатьЭлемент, заполнение реквизитов, Записать. Перед созданием проверяйте дубли, при синхронизации используйте УстановитьСсылкуНового, при массовой загрузке — транзакции порциями и тест на копии базы. Режим ОбменДанными.Загрузка ускоряет запись, но отключает проверки, поэтому применяется осознанно.