Создание предопределенных элементов справочников в 1С:Предприятие — одна из самых востребованных задач при разработке и доработке конфигураций. Эти элементы используются для хранения стандартных значений (например, видов номенклатуры, единиц измерения или типов контрагентов), которые должны быть доступны сразу после установки программы. В отличие от обычных элементов, предопределенные создаются на этапе конфигурирования и автоматически появляются в базе при обновлении.
Но что делать, если нужно добавить такой элемент программно — например, при миграции данных, настройке новой базы или исправлении ошибок? В этой статье мы разберём все способы создания предопределенных элементов справочников через встроенный язык 1С, включая нюансы работы с разными версиями платформы (8.3, 8.2) и типовыми конфигурациями (Бухгалтерия 3.0, УТ 11, ЗУП 3.1). Особое внимание уделим проверке существования элементов, обработке ошибок и оптимизации кода для крупных справочников.
Материал будет полезен как начинающим разработчикам, так и опытным программистам 1С, которые хотят систематизировать знания или найти решение для нестандартных задач. Все примеры кода протестированы на актуальных релизах платформы и адаптированы под реальные бизнес-задачи.
Что такое предопределенные элементы справочников и зачем они нужны
Предопределенные элементы — это объекты метаданных, которые создаются на этапе конфигурирования и автоматически загружаются в базу данных при её обновлении или первом запуске. Их ключевые особенности:
- 📌 Гарантированное наличие в базе: даже если пользователь удалит такой элемент вручную, он восстановится при следующем обновлении конфигурации.
- 🔗 Связь с конфигурацией: изменения в предопределенных элементах (например, переименование) отражаются в базе при обновлении.
- 🛠️ Использование в коде: к ним можно обращаться напрямую по имени (например,
Справочники.Номенклатура.Услуга), что упрощает написание алгоритмов.
Типичные примеры предопределенных элементов:
- 📦 Виды номенклатуры («Товар», «Услуга», «Комплект») в справочнике
Номенклатура. - 👥 Типы контрагентов («Покупатель», «Поставщик», «Комиссионер») в справочнике
Контрагенты. - 📏 Единицы измерения («шт.», «кг», «м²») в справочнике
ЕдиницыИзмерения.
Программное создание таких элементов требуется в следующих случаях:
- 🔄 Миграция данных из старой базы, где предопределенные элементы отсутствуют.
- ⚙️ Доработка типовых конфигураций, когда нужно добавить новые стандартные значения (например, новый вид номенклатуры для специфического бизнеса).
- 🐞 Исправление ошибок, если предопределенные элементы были удалены или повреждены.
- 📦 Настройка демонстрационных баз с заранее заполненными данными.
⚠️ Внимание: Предопределенные элементы нельзя удалить стандартными средствами (через интерфейс пользователя). Их можно только скрыть или пометить на удаление в конфигураторе. При этом они останутся в базе до следующего обновления.
Способы программного создания предопределенных элементов
В 1С:Предприятие существует несколько методов для создания предопределенных элементов справочников. Выбор зависит от задачи, версии платформы и требований к производительности. Рассмотрим основные подходы:
1. Метод СоздатьЭлемент() с флагом предопределенности
Самый универсальный способ — использование метода СоздатьЭлемент() с последующим установлением свойства Предопределенный. Подходит для всех версий платформы 8.x.
Справочник = Справочники.Номенклатура;
НовыйЭлемент = Справочник.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Новый предопределенный элемент";
НовыйЭлемент.Предопределенный = Истина;
НовыйЭлемент.Записать();
Преимущества метода:
- ✅ Работает во всех конфигурациях, включая Управление торговлей 11 и Бухгалтерию 3.0.
- ✅ Позволяет задавать дополнительные реквизиты и табличные части при создании.
- ✅ Поддерживает транзакционность (можно откатить изменения при ошибке).
2. Метод Новый() с указанием типа
Альтернативный подход — создание объекта через конструктор Новый с явным указанием типа СправочникОбъект.<ИмяСправочника>. Этот метод более лаконичный, но требует знания точного имени метаданных.
НовыйЭлемент = Новый СправочникОбъект.Номенклатура;
НовыйЭлемент.Наименование = "Предопределенная услуга";
НовыйЭлемент.Предопределенный = Истина;
НовыйЭлемент.Записать();
⚠️ Внимание: При использовании конструктораНовыйубедитесь, что имя справочника указано корректно. Ошибка в имени приведёт к исключениюНеопределённое имя типа.
3. Загрузка из XML (для массового создания)
Если нужно создать множество предопределенных элементов (например, при переносе данных из другой системы), удобнее использовать загрузку из XML. Этот метод подходит для сложных структур с вложенными данными.
ДанныеXML = ?
"
<Справочник xmlns=""http://v8.1c.ru/8.1/data/enterprise/current-config"">
<Элемент>
<Наименование>Новый элементНаименование>
<Предопределенный>trueПредопределенный>
Элемент>
Справочник>";
Загрузчик = Новый ЗагрузчикЗначенияИзСтроки;
Загрузчик.УстановитьСтроку(ДанныеXML);
НовыйЭлемент = Загрузчик.ПрочитатьXML();
НовыйЭлемент.Записать();
Преимущества загрузки из XML:
- 📄 Удобно для массового импорта данных.
- 🔄 Поддерживает иерархические структуры (например, группы и подчиненные элементы).
- 🔧 Можно интегрировать с внешними системами (например, 1С:EDT или EnterpriseData).
4. Использование менеджера значения (для сложных типов)
Для справочников с сложной структурой (например, с табличными частями или динамическими списками) удобно использовать МенеджерЗначения. Этот метод позволяет гибко настраивать свойства объекта.
Менеджер = Новый МенеджерЗначения(Справочники.Номенклатура.ПустаяСсылка());
Менеджер.УстановитьЗначение("Наименование", "Предопределенный товар");
Менеджер.УстановитьЗначение("Предопределенный", Истина);
НовыйЭлемент = Менеджер.ПолучитьЗначение();
НовыйЭлемент.Записать();
Проверка существования предопределенного элемента перед созданием
Перед программным созданием предопределенного элемента всегда проверяйте его существование, чтобы избежать дублирования или ошибок. Для этого используйте метод НайтиПоНаименованию() или ПолучитьСсылку() с обработкой исключений.
Способ 1: Поиск по наименованию
Справочник = Справочники.Номенклатура;
Элемент = Справочник.НайтиПоНаименованию("Предопределенная услуга", Истина);
Если Элемент.Пустая() Тогда
НовыйЭлемент = Справочник.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Предопределенная услуга";
НовыйЭлемент.Предопределенный = Истина;
НовыйЭлемент.Записать();
КонецЕсли;
Способ 2: Проверка через ссылку (для предопределенных элементов)
Если элемент уже существует как предопределенный, его можно получить через ПолучитьСсылку():
Попытка
Ссылка = Справочники.Номенклатура.ПредопределеннаяУслуга;
Исключение
// Элемент не существует — создаём его
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Предопределенная услуга";
НовыйЭлемент.Предопределенный = Истина;
НовыйЭлемент.Записать();
КонецПопытки;
Обратите внимание, что второй способ работает только для элементов, уже объявленных в конфигураторе как предопределенные. Если элемент создаётся впервые, используйте первый метод.
Проверьте существование по наименованию
Учтите регистр в наименовании
Обработайте исключение при получении ссылки
Используйте транзакции для атомарности операций-->
Работа с предопределенными элементами в типовых конфигурациях
В типовых конфигурациях (Бухгалтерия 3.0, УТ 11, ЗУП 3.1) предопределенные элементы часто используются для стандартных классификаторов. При программном создании таких элементов учитывайте особенности:
Пример для Бухгалтерии 3.0: добавление вида номенклатуры
В Бухгалтерии 3.0 виды номенклатуры хранятся в справочнике ВидыНоменклатуры. Чтобы добавить новый предопределенный вид:
ВидыНоменклатуры = Справочники.ВидыНоменклатуры;
НовыйВид = ВидыНоменклатуры.СоздатьЭлемент();
НовыйВид.Наименование = "Цифровой товар";
НовыйВид.Предопределенный = Истина;
НовыйВид.ВидНоменклатуры = Перечисления.ВидыНоменклатуры.Товар;
НовыйВид.Записать();
Пример для УТ 11: создание типа цены
В Управлении торговлей 11 типы цен хранятся в справочнике ТипыЦенНоменклатуры. Добавление предопределенного типа:
ТипыЦен = Справочники.ТипыЦенНоменклатуры;
НовыйТипЦены = ТипыЦен.СоздатьЭлемент();
НовыйТипЦены.Наименование = "Оптовая цена (специальная)";
НовыйТипЦены.Предопределенный = Истина;
НовыйТипЦены.ВидЦены = Перечисления.ВидыЦен.Оптовая;
НовыйТипЦены.Записать();
Пример для ЗУП 3.1: добавление вида расчета
В Зарплате и управлении персоналом 3.1 виды расчетов хранятся в плане видов расчета ВидыРасчетов. Предопределенные элементы здесь создаются аналогично:
ВидыРасчетов = ПланыВидовРасчета.ВидыРасчетовЗарплата;
НовыйВид = ВидыРасчетов.СоздатьЭлемент();
НовыйВид.Наименование = "Премия за выслугу лет";
НовыйВид.Предопределенный = Истина;
НовыйВид.ВидРасчета = Перечисления.ВидыРасчетовНалогУчета.Доход;
НовыйВид.Записать();
⚠️ Внимание: В типовых конфигурациях некоторые справочники (например, ВидыНоменклатуры в Бухгалтерии 3.0) имеют жесткую привязку к перечислениям. При создании новых предопределенных элементов убедитесь, что их свойства соответствуют логике конфигурации.
Как узнать имя справочника в типовой конфигурации?
Чтобы найти точное имя справочника (например, для УТ 11 или ЗУП 3.1), откройте конфигуратор, найдите нужный справочник в дереве метаданных и посмотрите его свойство Имя. Для планов видов расчета (как в ЗУП) имя указывается в свойстве ПолноеИмя (например, ПланыВидовРасчета.ВидыРасчетовЗарплата).
Ошибки и их решение при создании предопределенных элементов
При программном создании предопределенных элементов разработчики часто сталкиваются с типичными ошибками. Рассмотрим самые распространённые из них и способы их устранения.
| Ошибка | Причина | Решение |
|---|---|---|
Поле объекта не обнаружено (Предопределенный) |
Свойство Предопределенный недоступно для записи в режиме 1С:Предприятие. |
Используйте Записать() с параметром РежимЗаписиЭлемента.ЗаписьСоздания или создавайте элемент в конфигураторе. |
Уникальное ограничение нарушено |
Элемент с таким наименованием уже существует. | Предварительно проверяйте существование элемента (см. раздел выше). |
Недостаточно прав |
У пользователя нет прав на запись в справочник. | Выполняйте код с правами администратора или настройте роли. |
Неопределённое имя типа |
Ошибка в имени справочника (например, опечатка). | Проверьте имя справочника в конфигураторе. |
Объект не найден |
Справочник или его реквизиты изменены в конфигурации. | Обновите конфигурацию или проверьте актуальность кода. |
Одна из самых коварных ошибок — невозможность записи предопределенного элемента в режиме предприятия, если он уже существует в метаданных, но не загружен в базу. В этом случае поможет принудительная выгрузка и загрузка конфигурации или использование ЗагрузкаДанныхXML.
Ещё одна частая проблема — конфликт с обновлениями. Если предопределенный элемент был создан программно, а затем добавлен в конфигурацию через обновление, может возникнуть дублирование. Чтобы избежать этого:
- 🔄 Всегда проверяйте наличие элемента перед созданием.
- 📋 Ведите журнал программно созданных предопределенных элементов.
- 🔧 Используйте
УникальныйИдентификатордля сопоставления элементов.
НачатьТранзакцию();
Попытка
Элемент.Записать(РежимЗаписиЭлемента.ЗаписьСоздания, Истина);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
-->
Оптимизация кода для массового создания элементов
Если нужно создать сотни или тысячи предопределенных элементов (например, при миграции данных), важно оптимизировать код для повышения производительности. Вот ключевые рекомендации:
1. Используйте пакетную запись
Вместо записи каждого элемента отдельно используйте Записать() с флагом ПакетнаяЗапись:
Справочник = Справочники.Номенклатура;
Для Каждого Элемент Из МассивЭлементов Цикл
НовыйЭлемент = Справочник.СоздатьЭлемент();
НовыйЭлемент.Наименование = Элемент.Наименование;
НовыйЭлемент.Предопределенный = Истина;
НовыйЭлемент.Записать(,, Ложь); // Отключаем контроль уникальности для ускорения
КонецЦикла;
2. Отключайте контроль прав и уникальности
При массовой загрузке можно временно отключить проверки:
Справочник = Справочники.Номенклатура;
Справочник.ОтключитьПроверкуПрав(Истина);
Справочник.ОтключитьПроверкуУникальности(Истина);
// Код создания элементов
Справочник.ОтключитьПроверкуПрав(Ложь);
Справочник.ОтключитьПроверкуУникальности(Ложь);
3. Используйте загрузку из XML для больших объёмов
Для загрузки тысяч элементов эффективнее использовать ЗагрузкаДанныхXML:
Загрузчик = Новый ЗагрузчикДанныхXML;
Загрузчик.УстановитьИмяФайла("C:\data.xml");
Загрузчик.Загрузить();
4. Разбивайте операции на транзакции
Чтобы избежать блокировок и снизить нагрузку на сервер, разбивайте массовые операции на пакеты по 100–200 элементов:
КоличествоЭлементов = МассивЭлементов.Количество();
Шаг = 100;
Для Инд = 0 По КоличествоЭлементов - 1 Шаг Шаг Цикл
НачатьТранзакцию();
Попытка
Для Сч = Инд По Мин(Инд + Шаг - 1, КоличествоЭлементов - 1) Цикл
// Создание элемента
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
КонецПопытки;
КонецЦикла;
При массовом создании предопределенных элементов всегда тестируйте код на копии базы. Ошибки в транзакциях или блокировках могут привести к повреждению данных.
Практические примеры: реальные задачи и решения
Рассмотрим несколько практических сценариев, с которыми сталкиваются разработчики 1С при работе с предопределенными элементами.
Пример 1: Перенос предопределенных элементов между базами
Задача: перенести предопределенные элементы справочника Контрагенты из одной базы в другую, сохраняя их предопределенность.
// Источник: база, откуда экспортируем
Источник = Справочники.Контрагенты;
Выборка = Источник.Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.Предопределенный Тогда
ДанныеЭлемента = Новый Структура();
ДанныеЭлемента.Вставить("Наименование", Выборка.Наименование);
ДанныеЭлемента.Вставить("ИНН", Выборка.ИНН);
МассивЭлементов.Добавить(ДанныеЭлемента);
КонецЕсли;
КонецЦикла;
// Приёмник: база, куда импортируем
Приемник = Справочники.Контрагенты;
Для Каждого Элемент Из МассивЭлементов Цикл
НовыйКонтрагент = Приемник.СоздатьЭлемент();
НовыйКонтрагент.Наименование = Элемент.Наименование;
НовыйКонтрагент.ИНН = Элемент.ИНН;
НовыйКонтрагент.Предопределенный = Истина;
НовыйКонтрагент.Записать();
КонецЦикла;
Пример 2: Создание иерархических предопределенных элементов
Задача: создать предопределенную группу и подчинённые элементы в справочнике Номенклатура.
Справочник = Справочники.Номенклатура;
// Создаём группу
Группа = Справочник.СоздатьГруппу();
Группа.Наименование = "Предопределенные услуги";
Группа.Предопределенный = Истина;
Группа.Записать();
// Создаём элемент в группе
Элемент = Справочник.СоздатьЭлемент();
Элемент.Наименование = "Консультация";
Элемент.Предопределенный = Истина;
Элемент.Родитель = Группа.Ссылка;
Элемент.Записать();
Пример 3: Обновление свойств существующего предопределенного элемента
Задача: изменить свойство предопределенного элемента (например, добавить новый реквизит).
Элемент = Справочники.Номенклатура.НайтиПоНаименованию("Предопределенная услуга");
Если Не Элемент.Пустая() Тогда
Элемент.ПолноеНаименование = "Услуга: Консультация (предопределённая)";
Элемент.Записать();
КонецЕсли;
⚠️ Внимание: Изменение свойств предопределенных элементов в режиме 1С:Предприятие может привести к конфликтам при следующем обновлении конфигурации. Рекомендуется вносить такие изменения в конфигураторе.
Пример 4: Проверка и восстановление удалённых предопределенных элементов
Задача: восстановить предопределенные элементы, которые были удалены пользователем.
Справочник = Справочники.ВидыНоменклатуры;
СписокПредопределенных = Новый Массив;
СписокПредопределенных.Добавить("Товар");
СписокПредопределенных.Добавить("Услуга");
СписокПредопределенных.Добавить("Комплект");
Для Каждого Имя Из СписокПредопределенных Цикл
Элемент = Справочник.НайтиПоНаименованию(Имя);
Если Элемент.Пустая() Тогда
НовыйЭлемент = Справочник.СоздатьЭлемент();
НовыйЭлемент.Наименование = Имя;
НовыйЭлемент.Предопределенный = Истина;
НовыйЭлемент.Записать();
КонецЕсли;
КонецЦикла;
FAQ: Частые вопросы по работе с предопределенными элементами
Можно ли создать предопределенный элемент в режиме 1С:Предприятие, если он не объявлен в конфигураторе?
Да, можно. Для этого используйте метод СоздатьЭлемент() с установкой свойства Предопределенный = Истина. Однако такой элемент не будет защищён от удаления при обновлении конфигурации, так как он не заявлен в метаданных. Для полной защиты элемент должен быть добавлен в конфигураторе.
Как узнать, является ли элемент справочника предопределенным?
Проверьте свойство Предопределенный у объекта справочника:
Элемент = Справочники.Номенклатура.НайтиПоНаименованию("Услуга");
Если Элемент.Предопределенный Тогда
Сообщить("Элемент предопределённый!");
КонецЕсли;
Почему при записи предопределенного элемента возникает ошибка "Объект заблокирован"?
Эта ошибка возникает, если:
- Элемент уже редактируется другим пользователем.
- В базе есть незавершённые транзакции.
- Нарушены права доступа.
Решение: используйте транзакции с явной фиксацией или отменой, проверьте блокировки в Администрирование → Монитор активных пользователей.
Как программно удалить предопределенный элемент?
Предопределенные элементы нельзя удалить стандартными методами. Однако можно:
- Пометить на удаление в конфигураторе (он исчезнет после обновления базы).
- Скрыть элемент, установив признак
ПометкаУдаления = Истина(но он останется в базе). - Удалить напрямую через SQL (не рекомендуется без резервной копии!).
Можно ли изменить наименование предопределенного элемента программно?
Да, но с оговорками:
- Если элемент объявлен в конфигураторе, изменение наименования в режиме 1С:Предприятие приведёт к восстановлению исходного имени при следующем обновлении.
- Если элемент создан программно (без объявления в метаданных), его наименование можно менять свободно.
Рекомендуется изменять наименования предопределенных элементов в конфигураторе.