Как программно заполнить единицы измерения в регистре сведений Штрихкоды в УТ 10.3

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

При массовой загрузке данных в конфигурацию «Управление торговлей 10.3», особенно при использовании внешних обработок с диска ИТС, часто возникает ситуация, когда справочник Номенклатура заполняется корректно, а сопутствующие регистры — лишь частично. Одной из наиболее распространенных проблем является отсутствие привязки штрихкода к единице измерения в регистре сведений Штрихкоды.

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

Анализ структуры регистра и выявление причин проблемы

Прежде чем приступать к написанию кода, давайте проанализируем, как устроен регистр сведений Штрихкоды в УТ 10.3. Это независимый и непериодический регистр. Его ключевая особенность заключается в том, что поле ЕдиницаИзмерения является не ресурсом, а измерением.

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

Рассмотрим основные ошибки, с которыми сталкиваются разработчики при попытке автоматического исправления:

  1. Поле объекта не обнаружено (Номенклатура): В типовой конфигурации УТ 10.3 владельцем штрихкода в регистре выступает измерение Владелец, которое имеет составной тип (СправочникСсылка.Номенклатура или СправочникСсылка.СерииНоменклатуры). Обращение зап.Номенклатура вызывает ошибку, так как такого поля в метаданных нет.
  2. Штрихкод уже имеет владельца: Эта ошибка часто возникает из-за внутренних проверок в модуле набора записей или при попытке записать штрихкод, который уже существует в системе для этой же номенклатуры, но с другой единицей измерения.

Подготовительный этап: проверка данных запросом

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


ВЫБРАТЬ
    Штрихкоды.ТипШтрихкода,
    Штрихкоды.Штрихкод,
    Штрихкоды.Владелец КАК НоменклатураСсылка,
    Штрихкоды.Владелец.ЕдиницаХраненияОстатков КАК НужнаяЕдиница
ИЗ
    РегистрСведений.Штрихкоды КАК Штрихкоды
ГДЕ
    Штрихкоды.ЕдиницаИзмерения = ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)
    И Штрихкоды.Владелец ССЫЛКА Справочник.Номенклатура

Проанализируем результат запроса. Если поле НужнаяЕдиница заполнено, мы можем приступать к обработке. Если же оно пустое, значит, проблема глубже: у номенклатуры не заданы базовые единицы измерения, и сначала нужно исправить справочник Номенклатура.

Способ 1: Простой перебор набора записей (для небольших объемов)

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

Рассмотрим исправленный код, который обсуждался в сообщении №8 темы форума:


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

Способ 2: Оптимальный метод через Менеджер Записи

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

Разберем алгоритм по шагам:

  1. Создаем выборку записей, где единица измерения пуста.
  2. Для каждой записи получаем параметры (Штрихкод, Владелец, Тип).
  3. Удаляем старую запись.
  4. Записываем новую с заполненной единицей.

Выборка = РегистрыСведений.Штрихкоды.Выбрать();
Пока Выборка.Следующий() Цикл
    Если Выборка.ЕдиницаИзмерения.Пустая() Тогда
        
        // Получаем правильную единицу из владельца
        ТекЕдиница = Выборка.Владелец.ЕдиницаХраненияОстатков;
        
        Если ТекЕдиница.Пустая() Тогда
            Продолжить; // Пропускаем, если у товара нет единицы хранения
        КонецЕсли;

        // Создаем менеджер записи для удаления старой записи
        МЗ_Старый = РегистрыСведений.Штрихкоды.СоздатьМенеджерЗаписи();
        ЗаполнитьЗначенияСвойств(МЗ_Старый, Выборка);
        МЗ_Старый.Прочитать();
        Если МЗ_Старый.Выбран() Тогда
            МЗ_Старый.Удалить();
        КонецЕсли;

        // Создаем менеджер записи для новой записи
        МЗ_Новый = РегистрыСведений.Штрихкоды.СоздатьМенеджерЗаписи();
        ЗаполнитьЗначенияСвойств(МЗ_Новый, Выборка);
        МЗ_Новый.ЕдиницаИзмерения = ТекЕдиница;
        МЗ_Новый.Записать();
        
    КонецЕсли;
КонецЦикла;

Важные рекомендации при работе с РС «Штрихкоды»

Проанализируем возможные побочные эффекты. В УТ 10.3 штрихкоды могут быть привязаны не только к номенклатуре, но и к характеристикам. Если в вашей базе ведется учет по характеристикам, обязательно убедитесь, что при перезаписи поле ХарактеристикаНоменклатуры не очищается. В приведенном выше коде использование ЗаполнитьЗначенияСвойств помогает сохранить все измерения.

Транзакции и безопасность:

Рассмотрим ситуацию с ошибкой «Штрихкод уже имеет владельца». Она часто возникает, если вы пытаетесь присвоить единицу измерения, которая уже занята другим штрихкодом. В этом случае перед записью стоит добавить проверку на существование аналогичной записи в регистре, чтобы избежать прерывания работы обработки.

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

← На главную