При длительной работе в учетных системах 1С справочник номенклатуры неизбежно засоряется: в базу попадают дубли, ошибочно заведенные позиции или товары, по которым так и не начались продажи и закупки. Возникает задача — очистить базу от неиспользуемых позиций, переместить их в архивную группу или удалить вместе со связанными данными (ценами, единицами измерения, штрихкодами). Рассмотрим, почему стандартные интерактивные методы могут привести к потере данных, и разберем надежные программные и административные способы решения задачи.
Проанализируем распространенную ошибку: некоторые пользователи пытаются пометить на удаление целую папку с номенклатурой, запустить стандартную обработку Удаление помеченных объектов, а затем снять пометку с оставшихся элементов. Такой подход крайне опасен по следующим причинам:
Важное правило: любые массовые манипуляции со справочниками необходимо выполнять исключительно после создания полной резервной копии информационной базы.
Чтобы корректно определить, используется ли позиция, нужно проверить наличие внешних ссылок на сам товар и на все его подчиненные объекты единым пакетом. Если передать в платформенный метод НайтиПоСсылкам() массив, содержащий товар и связанные с ним элементы, платформа проигнорирует взаимные ссылки между ними и покажет только ссылки из внешних документов и регистров.
Разберем пример кода на платформе 1С:Предприятие 8, выполняющий поиск внешних ссылок и перемещение неиспользуемых элементов в специальную группу:
// Создаем или находим группу для неиспользуемых товаров
РодительБезДвижений = Справочники.Номенклатура.НайтиПоНаименованию("БезДвижений");
Если РодительБезДвижений.Пустая() Тогда
ГруппаОбъект = Справочники.Номенклатура.СоздатьГруппу();
ГруппаОбъект.Наименование = "БезДвижений";
ГруппаОбъект.Записать();
РодительБезДвижений = ГруппаОбъект.Ссылка;
КонецЕсли;
// Выбираем элементы номенклатуры
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ЭтоГруппа
| И Номенклатура.Родитель <> &РодительБезДвижений";
Запрос.УстановитьПараметр("РодительБезДвижений", РодительБезДвижений);
Результат = Запрос.Выполнить().Выгрузить();
Для Каждого Стр Из Результат Цикл
МассивДляПроверки = Новый Массив;
МассивДляПроверки.Добавить(Стр.Ссылка);
// Добавляем в массив подчиненные единицы измерения и цены для исключения ложных ссылок
ВыборкаЕдиниц = Справочники.ЕдиницыИзмерения.Выбрать(, Стр.Ссылка);
Пока ВыборкаЕдиниц.Следующий() Цикл
МассивДляПроверки.Добавить(ВыборкаЕдиниц.Ссылка);
КонецЦикла;
// Ищем только внешние ссылки
ТаблицаСсылок = НайтиПоСсылкам(МассивДляПроверки);
// Фильтруем внутренние ссылки из результата
ВнешнихСсылокНет = Истина;
Для Каждого СтрСсылка Из ТаблицаСсылок Цикл
Если МассивДляПроверки.Найти(СтрСсылка.Данные) = Неопределено Тогда
ВнешнихСсылокНет = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ВнешнихСсылокНет Тогда
ОбъектНоменклатура = Стр.Ссылка.ПолучитьОбъект();
ОбъектНоменклатура.Родитель = РодительБезДвижений;
ОбъектНоменклатура.УстановитьПометкуУдаления(Истина, Истина);
ОбъектНоменклатура.Записать();
КонецЕсли;
КонецЦикла;
Для платформы 1С 7.7 аналогичная задача решается с помощью метода НайтиСсылки(). При пакетной обработке для исключения блокировок из результатов анализа программно отсекают строки, где источник ссылки является подчиненным справочником проверяемого элемента (через проверку атрибута Владелец):
Спис = СоздатьОбъект("СписокЗначений");
Спис.ДобавитьЗначение(ТекНоменклатура);
ТЗСсылок = СоздатьОбъект("ТаблицаЗначений");
НайтиСсылки(Спис, ТЗСсылок);
// Проверяем, есть ли внешние ссылки
ЕстьВнешние = 0;
ТЗСсылок.ВыбратьСтроки();
Пока ТЗСсылок.ПолучитьСтроку() = 1 Цикл
СсылкаНаОбъект = ТЗСсылок.Объект;
// Если объект не подчинен текущей номенклатуре
Если СсылкаНаОбъект.Владелец <> ТекНоменклатура Тогда
ЕстьВнешние = 1;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЕстьВнешние = 0 Тогда
ТекНоменклатура.Удалить(1); // Пометка на удаление
КонецЕсли;
Если физическое удаление позиций несет риски нарушения целостности базы или в будущем планируется возобновление работы с товарами, рассмотрим более безопасные способы изоляции номенклатуры:
Недействителен (или признак закрытия позиции). Установка этого флага исключает товар из списков быстрого выбора, автоподбора в документах и отчетов, сохраняя при этом все связанные штрихкоды и историю.