Как массово пометить номенклатуру на удаление по списку из файла

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

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

Способ 1. Программная обработка текстового файла

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

Разберем по шагам логику работы кода:

  1. Открытие и чтение текстового файла.
  2. Обход каждой строки файла для получения названия товара.
  3. Поиск соответствующего элемента в справочнике Номенклатура.
  4. Установка пометки на удаление для найденного объекта.

Ниже представлен пример кода, который реализует этот алгоритм:


ТекстДок = Новый ТекстовыйДокумент;
ТекстДок.Прочитать(ПолноеИмяФайлаTXT, КодировкаТекста.UTF8);

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

Важный нюанс: при использовании метода НайтиПоНаименованию второй параметр Истина означает поиск по полному соответствию. Если в файле или в базе есть лишние пробелы, поиск может не дать результата. Поэтому мы используем функцию СокрЛП().

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

Для пользователей, которые не хотят прибегать к программированию, существует проверенный временем инструмент — ЗагрузкаДанныхИзТабличногоДокумента.epf. Этот метод мы проанализируем как «двухходовку».

Шаг 1. Подготовка и загрузка. Откроем обработку и выберем режим загрузки в справочник Номенклатура. На вкладке настройки необходимо выполнить следующие действия:

Шаг 2. Групповая обработка. После того как нужные элементы «помечены» особым комментарием или перемещены в папку, мы воспользуемся стандартной «Групповой обработкой справочников и документов». В ней мы установим отбор по нашему критерию (комментарию или папке) и выберем действие «Установить пометку на удаление».

Почему поиск по наименованию может не сработать?

Часто программисты сталкиваются с тем, что код «отрабатывает», но ничего не меняется. Выясним причину таких неудач:

  1. Невидимые символы. В названиях могут присутствовать неразрывные пробелы (код символа 160) или знаки табуляции. Визуально названия идентичны, но для системы это разные строки.
  2. Дубликаты. Метод НайтиПоНаименованию возвращает только первую найденную ссылку. Если в справочнике есть несколько товаров с одинаковым названием, обработана будет только одна позиция.
  3. Регистр сведений. Иногда данные, которые мы видим в списке товаров (например, штрихкоды или артикулы), хранятся не в самом справочнике, а в связанных регистрах. Проверьте, точно ли вы ищете по полю справочника.

Посмотрим на пример улучшения поиска. Чтобы избежать проблем с пробелами, можно использовать нормализацию строк:


Функция ОчиститьСтроку(Знач Стр)
    Стр = СтрЗаменить(Стр, Символы.НПП, " "); // Замена неразрывных пробелов
    Возврат СокрЛП(Стр);
КонецФункции

Безопасность и транзакции

Массовое изменение данных — это всегда риск. Мы настоятельно рекомендуем перед выполнением подобных операций делать резервную копию базы данных. Кроме того, программный код лучше оборачивать в транзакцию. Разберем ситуацию: если в процессе обработки 500-го элемента из 1000 произойдет сбой (например, отключится питание), без транзакции база останется в полуобработанном состоянии.


НачатьТранзакцию();
Попытка
    // Основной цикл обработки здесь
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    Сообщить("Произошла критическая ошибка, изменения не сохранены: " + ОписаниеОшибки());
КонецПопытки;

В современных конфигурациях (УТ 11, БП 3.0, ERP) для подобных задач рассмотрим подробнее встроенный механизм «Групповое изменение реквизитов» (находится в разделе Администрирование — Обслуживание). Он позволяет загружать списки значений напрямую и выполнять над ними операции без написания кода, используя встроенные алгоритмы сопоставления ссылок.

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

← На главную