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

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

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

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

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

Основной инструмент — объектная модель встроенного языка: менеджер справочника, объект элемента, методы записи и поиска. Для массовой загрузки дополнительно используют чтение файлов (CSV, Excel через табличный документ, XML) или средства обмена данными.

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

Как устроена программная работа со справочником

Любой справочник в 1С доступен через глобальный контекст Справочники. Менеджер конкретного справочника — например, Справочники.Номенклатура — предоставляет методы для создания, поиска и получения ссылок на элементы.

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

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

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

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

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

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

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

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

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

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

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

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

Создание групп и построение иерархии

Группы создаются отдельным методом СоздатьГруппу(). Типичный сценарий — сначала создать структуру папок, затем распределить по ним элементы.

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

Группа.Наименование = "Электрика";

Группа.Записать();

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

НовыйЭлемент.Наименование = "Выключатель одноклавишный";

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

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

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

Поиск перед записью и защита от дублей

Прямое создание элементов без проверки — главный источник задвоенных справочников. Перед созданием выполняйте поиск по ключевым полям: коду, наименованию или естественному ключу (например, ИНН для контрагентов, артикулу для товаров).

Ссылка = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7707083893");

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

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

НовыйКонтрагент.Наименование = "ООО Ромашка";

НовыйКонтрагент.ИНН = "7707083893";

НовыйКонтрагент.Записать();

Иначе

// Элемент уже есть — обновляем существующий

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

ОбъектКонтрагент.Наименование = "ООО Ромашка (обновлено)";

ОбъектКонтрагент.Записать();

КонецЕсли;

Метод НайтиПоНаименованию() ищет точное совпадение и ненадёжен для длинных наименований с разным регистром и пробелами. НайтиПоКоду() работает только если у справочника не отключена автонумерация и коды заполнены осмысленно. Самый надёжный вариант — поиск по реквизиту с уникальным значением через НайтиПоРеквизиту().

Типичные ошибки
01
Создание элементов без предварительного поиска — при повторном запуске загрузки справочник заполняется дублями
02
Присвоение строки реквизиту ссылочного типа — ошибка несоответствия типов при записи
03
Использование УстановитьСсылкуНового без контроля уникальности — конфликт ссылок при обмене данными
04
Запись в цикле без транзакции при больших объёмах — при сбое в середине часть данных загружена, часть нет, и откатить сложно

Заполнение табличных частей элемента

Многие справочники содержат табличные части — например, «Дополнительные реквизиты» или списки цен. Они заполняются как коллекция строк объекта: добавляется строка методом Добавить(), заполняются её поля, затем записывается весь объект целиком.

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

Объект.Наименование = "Краска белая, 10 л";

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

СтрокаСостава.Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизиты.НайтиПоНаименованию("Цвет");

СтрокаСостава.Значение = "Белый";

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

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

Массовая загрузка из файла

Классическая задача — заполнить справочник из CSV-файла или таблицы Excel. Файл читается построчно (текстовый документ, построитель запроса к табличному документу или чтение XML), каждая строка превращается в элемент справочника.

Текст = Новый ЧтениеТекста("C:\Загрузка\nomenklatura.csv", КодировкаТекста.UTF8);

СтрокаФайла = Текст.ПрочитатьСтроку();

Пока СтрокаФайла <> Неопределено Цикл

Части = СтрРазделить(СтрокаФайла, ";");

Если Части.Количество() >= 2 Тогда

Найденная = Справочники.Номенклатура.НайтиПоНаименованию(Части[0]);

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

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

Элемент.Наименование = Части[0];

Элемент.Артикул = Части[1];

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

КонецЕсли;

КонецЕсли;

СтрокаФайла = Текст.ПрочитатьСтроку();

КонецЦикла;

Текст.Закрыть();

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

Порядок безопасной массовой загрузки
  1. 1
    Сделайте резервную копию базы или разверните копию для теста
  2. 2
    Подготовьте файл и проверьте кодировку и разделитель на нескольких строках
  3. 3
    Напишите код загрузки с поиском дублей и транзакцией
  4. 4
    Запустите на копии, сверьте количество созданных элементов с количеством строк файла
  5. 5
    Проверьте несколько элементов вручную: реквизиты, родителя, ссылочные поля
  6. 6
    Только после проверки выполните загрузку в рабочую базу

Обработка ошибок и проверка результата

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

Если при загрузке не нужно срабатывание бизнес-логики (например, отправки уведомлений или записи в регистры), используйте Объект.ОбменДанными.Загрузка = Истина перед записью. Это отключает большинство проверок и ускоряет загрузку, но ответственность за корректность данных полностью ложится на ваш код.

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

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

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

Количество элементов
Норма

Число новых элементов равно числу строк файла минус найденные дубли

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

Элементов больше — значит, поиск дублей не сработал

Ссылочные реквизиты
Норма

Поля ссылаются на реальные элементы, открываются в форме

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

Битые ссылки вида «Объект не найден»

Обязательные реквизиты
Норма

Все помеченные в конфигураторе как обязательные поля заполнены

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

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

Альтернативы: типовые обработки загрузки

Писать собственный код не всегда обязательно. В типовых конфигурациях на БСП есть встроенная обработка «Загрузка данных из табличного документа», которая умеет сопоставлять колонки файла с реквизитами справочника и искать дубли без программирования. Для сложных переносов между конфигурациями применяют «Конвертацию данных» и универсальный обмен XML.

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

Способы заполнения справочника

Собственный код на встроенном языке

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

Загрузка из табличного документа (БСП)

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

Конвертация данных / обмен XML

Для переноса между конфигурациями с разной структурой. Требует настройки правил обмена

Частые вопросы

Как заполнить справочник, если у него отключена автонумерация и код пустой?

Код можно задать вручную: Элемент.Код = "000001" перед записью. Если код не используется в учёте, проще искать дубли по реквизиту или наименованию, а код оставить пустым — платформа это допускает при нулевой длине кода или ручной нумерации.

Почему при записи возникает ошибка «Поле объекта не обнаружено»?

Имя реквизита в коде не совпадает с именем в конфигураторе. Откройте конфигуратор, найдите справочник и сверьте точное имя реквизита — оно может отличаться от отображаемого синонима, который вы видите в форме.

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

Обязательно заполните реквизит Владелец ссылкой на элемент справочника-владельца до вызова Записать(). Без владельца платформа откажет в записи, так как элемент подчинённого справочника не существует сам по себе.

Можно ли отменить массовую загрузку после её завершения?

Если загрузка выполнялась без транзакции и уже зафиксирована — автоматически нет. Варианты: восстановление из резервной копии или написание обратного кода, который помечает созданные элементы на удаление по сохранённому списку ссылок. Поэтому список созданных ссылок стоит логировать при каждой загрузке.

Что быстрее: запись каждого элемента отдельно или пакетная?

Платформа записывает элементы справочника по одному — пакетной вставки как в SQL нет. Ускорить процесс можно отключением проверок через ОбменДанными.Загрузка и уменьшением числа обращений к базе (например, заранее закэшировать найденные ссылки в соответствие вместо повторного поиска).

Как заполнить справочник из Excel без сохранения в CSV?

Файл Excel можно прочитать через объект ТабличныйДокумент: метод Прочитать() загружает xlsx-файл, далее ячейки обходятся через Область() построчно. Это избавляет от промежуточного CSV, но работает медленнее на больших файлах.

Итог

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

Заполнение справочника строится на цепочке «создать объект → заполнить реквизиты → записать». Перед созданием ищите дубли по уникальному ключу, ссылочные реквизиты заполняйте ссылками, массовую загрузку выполняйте в транзакции и только после проверки на копии базы. Для простых разовых задач используйте типовую обработку загрузки из табличного документа.