Справочники и Данные · 12 мин
Как программно заполнить справочник в 1С
Как программно заполнить справочник 1С: создание элементов и групп, поиск дублей, заполнение табличных частей, загрузка из файла. Примеры кода на встроенном языке.
Программное заполнение справочника в 1С — стандартная задача при первоначальном внедрении, миграции данных из другой системы или регулярной синхронизации с внешними источниками. Вместо ручного ввода сотен позиций разработчик пишет код, который создаёт элементы, заполняет реквизиты и записывает их в базу за секунды.
Основной инструмент — объектная модель встроенного языка: менеджер справочника, объект элемента, методы записи и поиска. Для массовой загрузки дополнительно используют чтение файлов (CSV, Excel через табличный документ, XML) или средства обмена данными.
Ниже разобраны базовые приёмы: создание элемента и группы, поиск перед записью, заполнение табличных частей, загрузка из файла, а также типичные ошибки, которые приводят к дублям и повреждению данных. Примеры приведены для обычного приложения и управляемых форм — синтаксис объектной модели в обоих случаях одинаков.
Как устроена программная работа со справочником
Любой справочник в 1С доступен через глобальный контекст Справочники. Менеджер конкретного справочника — например, Справочники.Номенклатура — предоставляет методы для создания, поиска и получения ссылок на элементы.
Ключевой принцип: существует два разных объекта. Ссылка — это лёгкий указатель на элемент в базе, с ним нельзя работать как с редактируемыми данными. Объект — полная копия элемента в памяти, которую можно изменять и записывать. Объект получают либо созданием нового элемента (СоздатьЭлемент()), либо методом ПолучитьОбъект() у существующей ссылки.
Запись в базу происходит только при вызове Записать(). До этого момента все изменения существуют лишь в памяти. Если код прервётся с ошибкой до записи — база останется нетронутой, что удобно при отладке.
Создание одного элемента справочника
Минимальный код создания элемента выглядит так: получаем новый объект, заполняем реквизиты, записываем. Имена реквизитов указываются так, как они заданы в конфигураторе.
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Кабель ВВГнг 3х2,5";
НовыйЭлемент.Артикул = "КБ-00325";
НовыйЭлемент.ЕдиницаИзмерения = Справочники.ЕдиницыИзмерения.НайтиПоКоду("796");
НовыйЭлемент.Записать();
Сообщить("Создан элемент: " + НовыйЭлемент.Ссылка);
Обратите внимание на реквизит ЕдиницаИзмерения: если реквизит имеет ссылочный тип, ему нельзя присвоить строку — нужна ссылка на элемент другого справочника. Её получают поиском или созданием. Это одна из самых частых причин ошибки «Несоответствие типов» при загрузке.
Если у справочника включена иерархия и нужно положить элемент в конкретную папку, заполните реквизит Родитель ссылкой на группу. Для подчинённых справочников (например, «Единицы измерения» подчинены «Номенклатуре») обязательно заполняется Владелец — без него запись завершится ошибкой.
Создание групп и построение иерархии
Группы создаются отдельным методом СоздатьГруппу(). Типичный сценарий — сначала создать структуру папок, затем распределить по ним элементы.
Группа = Справочники.Номенклатура.СоздатьГруппу();
Группа.Наименование = "Электрика";
Группа.Записать();
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Выключатель одноклавишный";
НовыйЭлемент.Родитель = Группа.Ссылка;
НовыйЭлемент.Записать();
При многоуровневой иерархии удобно написать функцию, которая ищет группу по наименованию и родителю, а при отсутствии — создаёт её. Тогда повторный запуск загрузки не породит дубли папок.
Поиск перед записью и защита от дублей
Прямое создание элементов без проверки — главный источник задвоенных справочников. Перед созданием выполняйте поиск по ключевым полям: коду, наименованию или естественному ключу (например, ИНН для контрагентов, артикулу для товаров).
Ссылка = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7707083893");
Если Ссылка.Пустая() Тогда
НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.Наименование = "ООО Ромашка";
НовыйКонтрагент.ИНН = "7707083893";
НовыйКонтрагент.Записать();
Иначе
// Элемент уже есть — обновляем существующий
ОбъектКонтрагент = Ссылка.ПолучитьОбъект();
ОбъектКонтрагент.Наименование = "ООО Ромашка (обновлено)";
ОбъектКонтрагент.Записать();
КонецЕсли;
Метод НайтиПоНаименованию() ищет точное совпадение и ненадёжен для длинных наименований с разным регистром и пробелами. НайтиПоКоду() работает только если у справочника не отключена автонумерация и коды заполнены осмысленно. Самый надёжный вариант — поиск по реквизиту с уникальным значением через НайтиПоРеквизиту().
Заполнение табличных частей элемента
Многие справочники содержат табличные части — например, «Дополнительные реквизиты» или списки цен. Они заполняются как коллекция строк объекта: добавляется строка методом Добавить(), заполняются её поля, затем записывается весь объект целиком.
Объект = Справочники.Номенклатура.СоздатьЭлемент();
Объект.Наименование = "Краска белая, 10 л";
СтрокаСостава = Объект.ДополнительныеРеквизиты.Добавить();
СтрокаСостава.Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизиты.НайтиПоНаименованию("Цвет");
СтрокаСостава.Значение = "Белый";
Объект.Записать();
Табличная часть не записывается отдельно — она сохраняется вместе с объектом. Если нужно полностью заменить содержимое у существующего элемента, сначала очистите коллекцию методом Очистить(), затем добавьте новые строки.
Массовая загрузка из файла
Классическая задача — заполнить справочник из CSV-файла или таблицы Excel. Файл читается построчно (текстовый документ, построитель запроса к табличному документу или чтение XML), каждая строка превращается в элемент справочника.
Текст = Новый ЧтениеТекста("C:\Загрузка\nomenklatura.csv", КодировкаТекста.UTF8);
СтрокаФайла = Текст.ПрочитатьСтроку();
Пока СтрокаФайла <> Неопределено Цикл
Части = СтрРазделить(СтрокаФайла, ";");
Если Части.Количество() >= 2 Тогда
Найденная = Справочники.Номенклатура.НайтиПоНаименованию(Части[0]);
Если Найденная.Пустая() Тогда
Элемент = Справочники.Номенклатура.СоздатьЭлемент();
Элемент.Наименование = Части[0];
Элемент.Артикул = Части[1];
Элемент.Записать();
КонецЕсли;
КонецЕсли;
СтрокаФайла = Текст.ПрочитатьСтроку();
КонецЦикла;
Текст.Закрыть();
Для больших объёмов оберните загрузку в транзакцию (НачатьТранзакцию() / ЗафиксироватьТранзакцию() / ОтменитьТранзакцию()): при любой ошибке база вернётся в исходное состояние. Компромисс — транзакция на десятки тысяч записей увеличивает нагрузку и время блокировок, поэтому на очень больших файлах фиксируют порциями, например каждые 1000 элементов.
- 1Сделайте резервную копию базы или разверните копию для теста
- 2Подготовьте файл и проверьте кодировку и разделитель на нескольких строках
- 3Напишите код загрузки с поиском дублей и транзакцией
- 4Запустите на копии, сверьте количество созданных элементов с количеством строк файла
- 5Проверьте несколько элементов вручную: реквизиты, родителя, ссылочные поля
- 6Только после проверки выполните загрузку в рабочую базу
Обработка ошибок и проверка результата
Запись элемента может не пройти из-за проверок, заложенных в конфигурацию: обработчики ПередЗаписью и ПриЗаписи, проверка заполнения обязательных реквизитов, подписки на события. Поэтому вызов Записать() следует помещать в конструкцию Попытка ... Исключение и логировать текст ошибки вместе с данными строки, на которой произошёл сбой.
Если при загрузке не нужно срабатывание бизнес-логики (например, отправки уведомлений или записи в регистры), используйте Объект.ОбменДанными.Загрузка = Истина перед записью. Это отключает большинство проверок и ускоряет загрузку, но ответственность за корректность данных полностью ложится на ваш код.
После загрузки обязательно сверьте результат: количество элементов в справочнике до и после, число созданных и обновлённых записей из лога, отсутствие элементов с пустыми обязательными реквизитами. Простой запрос в консоли запросов по группировке наименований быстро покажет дубли.
Как проверить результат загрузки
Число новых элементов равно числу строк файла минус найденные дубли
Элементов больше — значит, поиск дублей не сработал
Поля ссылаются на реальные элементы, открываются в форме
Битые ссылки вида «Объект не найден»
Все помеченные в конфигураторе как обязательные поля заполнены
Пустые значения, элементы не проводятся в документах
Альтернативы: типовые обработки загрузки
Писать собственный код не всегда обязательно. В типовых конфигурациях на БСП есть встроенная обработка «Загрузка данных из табличного документа», которая умеет сопоставлять колонки файла с реквизитами справочника и искать дубли без программирования. Для сложных переносов между конфигурациями применяют «Конвертацию данных» и универсальный обмен XML.
Собственный код оправдан, когда нужна нестандартная логика: вычисляемые поля, сложный поиск по нескольким реквизитам, создание связанных элементов в разных справочниках одновременно. Для разовой простой загрузки типовая обработка быстрее и безопаснее.
Способы заполнения справочника
Полный контроль логики, подходит для регулярной синхронизации. Требует навыков разработки и тестирования на копии
Не требует программирования, есть сопоставление колонок и поиск дублей. Ограничена стандартными сценариями
Для переноса между конфигурациями с разной структурой. Требует настройки правил обмена
Частые вопросы
Как заполнить справочник, если у него отключена автонумерация и код пустой?
Код можно задать вручную: Элемент.Код = "000001" перед записью. Если код не используется в учёте, проще искать дубли по реквизиту или наименованию, а код оставить пустым — платформа это допускает при нулевой длине кода или ручной нумерации.
Почему при записи возникает ошибка «Поле объекта не обнаружено»?
Имя реквизита в коде не совпадает с именем в конфигураторе. Откройте конфигуратор, найдите справочник и сверьте точное имя реквизита — оно может отличаться от отображаемого синонима, который вы видите в форме.
Как создать элемент подчинённого справочника?
Обязательно заполните реквизит Владелец ссылкой на элемент справочника-владельца до вызова Записать(). Без владельца платформа откажет в записи, так как элемент подчинённого справочника не существует сам по себе.
Можно ли отменить массовую загрузку после её завершения?
Если загрузка выполнялась без транзакции и уже зафиксирована — автоматически нет. Варианты: восстановление из резервной копии или написание обратного кода, который помечает созданные элементы на удаление по сохранённому списку ссылок. Поэтому список созданных ссылок стоит логировать при каждой загрузке.
Что быстрее: запись каждого элемента отдельно или пакетная?
Платформа записывает элементы справочника по одному — пакетной вставки как в SQL нет. Ускорить процесс можно отключением проверок через ОбменДанными.Загрузка и уменьшением числа обращений к базе (например, заранее закэшировать найденные ссылки в соответствие вместо повторного поиска).
Как заполнить справочник из Excel без сохранения в CSV?
Файл Excel можно прочитать через объект ТабличныйДокумент: метод Прочитать() загружает xlsx-файл, далее ячейки обходятся через Область() построчно. Это избавляет от промежуточного CSV, но работает медленнее на больших файлах.
Что важно запомнить
Заполнение справочника строится на цепочке «создать объект → заполнить реквизиты → записать». Перед созданием ищите дубли по уникальному ключу, ссылочные реквизиты заполняйте ссылками, массовую загрузку выполняйте в транзакции и только после проверки на копии базы. Для простых разовых задач используйте типовую обработку загрузки из табличного документа.