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

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

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

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

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

Основной инструмент — менеджер справочника и его метод СоздатьГруппу(). Он возвращает объект типа «СправочникОбъект», который после заполнения записывается в базу методом Записать(). Тот же подход работает для планов видов характеристик и планов счетов, где также поддерживается иерархия.

Ниже разобран полный цикл: проверка условий, создание группы, установка родителя, поиск дублей, типичные ошибки и контроль результата. Примеры приведены на встроенном языке 1С и подходят для платформы 8.3 как в толстом, так и в тонком клиенте (с учётом выполнения кода на сервере).

Проверка предварительных условий

Прежде чем писать код, убедитесь, что справочник вообще поддерживает группы. Откройте конфигуратор, найдите нужный справочник и проверьте свойство «Иерархический» — оно должно быть установлено. Дополнительно посмотрите вид иерархии: «Иерархия групп и элементов» означает, что группы существуют отдельно от элементов, а «Иерархия элементов» — что любой элемент может быть родителем другого, и отдельного метода создания группы там нет.

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

Второе условие — права доступа. Пользователь, под которым выполняется код, должен иметь право «Добавление» и «Запись» на справочник. В клиент-серверном режиме код создания должен выполняться на сервере: директива &НаСервере или вызов серверной процедуры общего модуля. Попытка создать объект на клиенте в тонком клиенте приведёт к ошибке «Операция не может быть выполнена».

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

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

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

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

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

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

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

Обратите внимание: до вызова Записать() группа существует только в памяти. Если процедура завершится с ошибкой до записи, в базе ничего не появится. Это удобно для предварительной валидации — можно заполнить объект, проверить данные и только потом фиксировать.

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

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

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

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

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

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

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

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

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

КонецЕсли;

Второй параметр НайтиПоНаименованию — признак точного соответствия. Без него поиск идёт по началу строки, что может вернуть не ту группу. Более надёжный вариант — поиск по коду или по паре «наименование + родитель», чтобы отличать одноимённые группы в разных ветках дерева.

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

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

Создание группы без проверки существования — самая частая причина задвоения структуры справочника. Платформа не запрещает несколько групп с одинаковым наименованием у одного родителя, поэтому контроль ложится на разработчика.

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

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

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура

|ГДЕ Наименование = &Наименование И Родитель = &Родитель И ЭтоГруппа";

Запрос.УстановитьПараметр("Наименование", Наименование);

Запрос.УстановитьПараметр("Родитель", Родитель);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

Возврат Выборка.Ссылка;

КонецЕсли;

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

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

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

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

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

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

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

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

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

Тот же механизм работает для других иерархических объектов. План видов характеристик (например, «Дополнительные реквизиты и сведения» в типовых конфигурациях) поддерживает СоздатьГруппу(), если в его свойствах включена иерархия:

ГруппаПВХ = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.СоздатьГруппу();

ГруппаПВХ.Наименование = "Свойства товаров";

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

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

Сравнение вариантов

СоздатьГруппу()

Для иерархии «групп и элементов». Группа не содержит реквизитов элементов, служит только контейнером.

СоздатьЭлемент() с указанием Родителя

Для иерархии элементов, где любой элемент может быть родителем. Отдельных групп в такой модели нет.

Загрузка через типовые обработки

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

Транзакции и массовое создание

При загрузке сотен групп и элементов оборачивайте процесс в транзакцию: НачатьТранзакцию() перед циклом и ЗафиксироватьТранзакцию() после успешного завершения. В блоке исключения вызывайте ОтменитьТранзакцию(). Тогда сбой на середине не оставит в базе обрезанную структуру.

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

Проверка результата

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

Признак успешной записи — непустая ссылка у объекта после Записать(). Если запись не удалась, платформа вызывает исключение с описанием причины: нарушение уникальности кода, отсутствие прав, заполненность обязательных реквизитов. Текст исключения стоит логировать в журнал регистрации через ЗаписьЖурналаРегистрации(), чтобы при массовой загрузке видеть, на каких строках возникли проблемы.

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

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

Ссылка после Записать()
Норма

Ссылка непустая, группа открывается в форме списка

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

Исключение при записи или пустая ссылка

Положение в дереве
Норма

Группа отображается под нужным родителем

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

Группа в корне или не в той ветке

Тип объекта
Норма

В запросе ЭтоГруппа = Истина

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

Создан элемент вместо группы

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

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

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

Почему метод СоздатьГруппу() недоступен?

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

Как переместить существующую группу в другую ветку?

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

Можно ли создать группу с определённым кодом?

Да, если для справочника разрешена ручная нумерация. Присвойте свойству Код нужное значение до записи. При автонумерации платформа присвоит код сама, а принудительная установка может вызвать ошибку уникальности.

Как создать группу внешней обработкой без изменения конфигурации?

Изменять конфигурацию не требуется: внешняя обработка выполняет тот же код СоздатьГруппу() и Записать(). Достаточно, чтобы у пользователя были права на добавление в справочник, а код выполнялся на сервере в тонком клиенте.

Что делать, если при записи возникает ошибка блокировки?

Ошибка «Конфликт блокировок» означает, что другой сеанс изменяет связанные данные. Повторите попытку через небольшую паузу, сократите длину транзакции или выполняйте загрузку в монопольное время.

Итог

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

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