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

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

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

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

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

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

Ниже разобраны готовые примеры кода, способы проверки на дубли, особенности иерархии разных видов и типичные ошибки, которые приводят к «потерянным» группам и битым ссылкам.

Базовый код создания группы справочника

Минимальный пример выглядит так. Создаём объект группы, заполняем наименование и записываем:

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

НоваяГруппа.Наименование = "Импортированные товары";

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

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

Если у справочника есть дополнительные реквизиты, применимые к группам, их заполняют как обычные свойства объекта:

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

НоваяГруппа.Наименование = "Материалы";

НоваяГруппа.Комментарий = "Создано обработкой загрузки";

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

Учтите: не все реквизиты справочника доступны для групп. В конфигураторе у реквизита есть свойство использования — «Для элемента», «Для группы» или «Для группы и элемента». Если реквизит доступен только для элемента, обращение к нему у объекта группы вызовет ошибку.

Как проверить, поддерживает ли справочник группы

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

Проверить вид иерархии можно программно через метаданные:

ВидИерархии = Метаданные.Справочники.Номенклатура.ВидИерархии;

Если ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда

// группы доступны

КонецЕсли;

Вид «Иерархия групп и элементов» означает классические папки: группа содержит элементы и другие группы. Вид «Иерархия элементов» устроен иначе — там родителем элемента выступает другой элемент, и отдельных групп как таковых нет, хотя метод СоздатьГруппу() формально может быть доступен в зависимости от настроек.

Создание вложенной группы: как указать родителя

Чтобы создать подгруппу внутри существующей группы, нужно заполнить реквизит Родитель ссылкой на родительскую группу. Ссылку получают поиском или используют уже известную:

РодительскаяГруппа = Справочники.Номенклатура.НайтиПоНаименованию("Материалы", Истина);

Если Не РодительскаяГруппа.Пустая() Тогда

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

Подгруппа.Наименование = "Металлопрокат";

Подгруппа.Родитель = РодительскаяГруппа;

Подгруппа.Записать();

КонецЕсли;

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

Родителем можно назначить только группу. Если попытаться записать в Родитель ссылку на обычный элемент, платформа выдаст ошибку при записи объекта.

Порядок создания вложенной структуры
  1. 1
    Найдите или создайте родительскую группу верхнего уровня и запишите её
  2. 2
    Получите ссылку на родителя через объект.Ссылка после записи
  3. 3
    Создайте подгруппу методом СоздатьГруппу() и заполните Родитель
  4. 4
    Запишите подгруппу и повторите для следующего уровня вложенности
  5. 5
    Проверьте результат в форме списка справочника в режиме дерева

Проверка на дубли перед созданием

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

Функция ПолучитьГруппу(НаименованиеГруппы, Родитель = Неопределено)

ГруппаСсылка = Справочники.Номенклатура.НайтиПоНаименованию(

НаименованиеГруппы, Истина, Родитель);

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

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

НоваяГруппа.Наименование = НаименованиеГруппы;

Если Родитель <> Неопределено Тогда

НоваяГруппа.Родитель = Родитель;

КонецЕсли;

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

ГруппаСсылка = НоваяГруппа.Ссылка;

КонецЕсли;

Возврат ГруппаСсылка;

КонецФункции

Такая функция-обёртка решает сразу две задачи: ищет существующую группу и создаёт её при необходимости. Это удобно при загрузке многоуровневых классификаторов, где одна и та же группа встречается в данных многократно.

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

Типичные ошибки
01
Использование СоздатьЭлемент() вместо СоздатьГруппу() — вместо папки создаётся обычный элемент, который нельзя назначить родителем
02
Поиск дублей без учёта родителя — одноимённые группы в разных ветках считаются дублями или, наоборот, плодятся
03
Заполнение реквизита, недоступного для групп, — ошибка обращения к свойству объекта при выполнении
04
Запись подгруппы до записи родителя — ссылка родителя ещё пустая, Родитель остаётся незаполненным

Создание групп в транзакции и при обмене данными

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

НачатьТранзакцию();

Попытка

// создание групп и подгрупп

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ВызватьИсключение ОписаниеОшибки();

КонецПопытки;

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

Для объектов, участвующих в планах обмена, альтернативный вариант — установить ОбменДанными.Отправитель, чтобы платформа корректно обработала полученные данные без лишней регистрации.

Проверка результата и альтернативные способы

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

Признаки корректного создания: у группы заполнена ссылка, ЭтоГруппа = Истина, Родитель указывает на нужную группу, пометка удаления снята. Если группа видна в списке, но в неё нельзя поместить элементы — скорее всего, был создан элемент вместо группы.

Альтернативы ручному коду: типовая обработка «Универсальный обмен данными в формате XML», загрузка данных из табличного документа (в типовых конфигурациях), а также механизм СКД и консоль кода для разовых операций. Для разового заполнения небольшой структуры быстрее создать группы вручную — программный способ оправдан при повторяющихся загрузках и объёмах от десятков групп.

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

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

Свойство ЭтоГруппа у созданной ссылки
Норма

Равно Истина

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

Равно Ложь — создан обычный элемент, а не группа

Реквизит Родитель
Норма

Содержит ссылку на нужную родительскую группу

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

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

Отображение в форме списка
Норма

Группа видна как папка в режиме дерева

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

Группы нет или она отображается как элемент без значка папки

Часто задаваемые вопросы

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

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

Можно ли программно превратить существующий элемент в группу?

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

Почему НайтиПоНаименованию не находит созданную группу?

Чаще всего группа ещё не записана — поиск работает только по данным базы. Также проверьте второй параметр метода: без точного соответствия поиск идёт по началу наименования. Ещё одна причина — лишние пробелы или невидимые символы в наименовании из внешнего файла.

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

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

Нужны ли особые права для программного создания групп?

Да, у пользователя, от имени которого выполняется код, должно быть право добавления и изменения для данного справочника. В привилегированном модуле или при установке привилегированного режима проверка прав отключается, что используют в серверных процедурах загрузки данных.

Будут ли созданные группы участвовать в обмене данными?

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

Итог

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

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