Как в 1С удалить все элементы справочника Номенклатура, кроме родительских групп

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Разбор логической ошибки: почему удаляются группы?

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


Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    Если Выборка.ЭтоГруппа = Истина Тогда
        ОбъектСправочника = Выборка.ПолучитьОбъект();
        ОбъектСправочника.Удалить();
    КонецЕсли;
КонецЦикла;

В данном примере условие Если Выборка.ЭтоГруппа = Истина буквально приказывает системе: «Если текущая запись является папкой — удали её». В результате мы получаем пустой справочник. Чтобы оставить группы и удалить только товары, нам нужно инвертировать условие. Правильная логика должна звучать так: «Если это не группа, тогда удаляй».

Способ 1. Программный перебор с проверкой флага иерархии

Для небольших справочников можно использовать простой перебор выборки. Выясним причину, почему важно проверять свойство ЭтоГруппа. В 1С справочники с иерархией групп и элементов разделяют записи на два типа. Свойство ЭтоГруппа имеет значение Истина для папок и Ложь для конечных элементов.

Правильный алгоритм действий будет выглядеть следующим образом:

  1. Создаем выборку всех элементов справочника Номенклатура.
  2. В цикле проверяем тип текущей записи.
  3. Если это элемент (не группа), получаем объект и выполняем действие.

Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    // Проверяем, что это НЕ группа
    Если Не Выборка.ЭтоГруппа Тогда 
        Попытка
            ОбъектСправочника = Выборка.ПолучитьОбъект();
            // Используем Удалить() для полного удаления или УстановитьПометкуУдаления()
            ОбъектСправочника.Удалить(); 
        Исключение
            Сообщить("Не удалось удалить элемент: " + Выборка.Наименование + ". Возможно, он заблокирован.");
        КонецПопытки;
    КонецЕсли;
КонецЦикла;

Способ 2. Использование запроса для точной выборки

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

Рассмотрим, как составить правильный запрос для получения только элементов:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	Номенклатура.ЭтоГруппа = ЛОЖЬ";

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

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    Объект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
    Объект.Удалить();
КонецЦикла;

Этот подход экономит ресурсы сервера, так как РезультатЗапроса будет содержать только ссылки на товары, полностью исключая папки еще на этапе обращения к СУБД.

Важный нюанс: Непосредственное удаление vs Пометка на удаление

В примерах выше мы использовали метод Удалить(). Проанализируем ситуацию: что произойдет, если товар уже был продан в документах «Реализация товаров и услуг»? При использовании Удалить() запись исчезнет из базы физически. В документах вместо названия товара появится пугающая надпись <Объект не найден>. Это нарушит ссылочную целостность базы и сделает невозможным формирование отчетов за прошлые периоды.

Рекомендуем использовать метод УстановитьПометкуУдаления(Истина). Рассмотрим подробнее преимущества этого метода:

Пример безопасного кода:


Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    Объект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
    // Помечаем на удаление вместо физического стирания
    Объект.УстановитьПометкуУдаления(Истина); 
КонецЦикла;

Способ 3. Удаление элементов в конкретных группах

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


СписокГрупп = Новый Массив;
СписокГрупп.Добавить(Справочники.Номенклатура.НайтиПоНаименованию("Летние"));
СписокГрупп.Добавить(Справочники.Номенклатура.НайтиПоНаименованию("Зимние"));

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	Номенклатура.Родитель В ИЕРАРХИИ(&СписокГрупп)
    |	И Номенклатура.ЭтоГруппа = ЛОЖЬ";

Запрос.УстановитьПараметр("СписокГрупп", СписокГрупп);
// Далее стандартный цикл обработки...

Использование стандартных инструментов (без кода)

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

  1. Откройте меню «Администрирование» — «Обслуживание».
  2. Перейдите в раздел «Корректировка данных» и выберите «Групповое изменение реквизитов».
  3. В поле «Изменять» выберите справочник Номенклатура.
  4. Нажмите «Добавить условие отбора» и укажите: Это группа Равно Нет.
  5. В списке реквизитов найдите поле Пометка удаления и установите значение Да.
  6. Нажмите кнопку «Изменить реквизиты».

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

Проанализировав все способы, мы видим, что наиболее эффективным для программиста является использование Запроса с фильтром ЭтоГруппа = ЛОЖЬ и последующей установкой пометки удаления. Это гарантирует скорость работы и сохранность данных в учетной системе.

← На главную