Как сгенерировать уникальные штрихкоды для каждой единицы номенклатуры в 1С?

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

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

Постановка задачи и базовые подходы

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

Для решения этой задачи нам предстоит выполнить следующие шаги:

  1. Определить подходящий механизм для генерации уникальных штрихкодов.
  2. Выбрать способ хранения этих штрихкодов таким образом, чтобы они были привязаны к конкретному экземпляру товара.
  3. Интегрировать логику генерации в документ оприходования.
  4. Обеспечить возможность поиска номенклатуры по уникальному штрихкоду.
  5. Рассмотреть вопросы оптимизации и использования стандартных возможностей 1С.

Особенности уникальной идентификации: почему не подходит стандартный EAN13

Многие из нас привыкли использовать штрихкоды формата EAN13 для товаров. Однако нам важно понимать, что штрихкод EAN13, как правило, идентифицирует вид товара или тип номенклатуры, а не ее конкретный физический экземпляр. Если у нас есть 30 одинаковых кружек с одним и тем же EAN13, мы не сможем по нему различить каждую кружку в отдельности.

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

Важно: Если вы планируете использовать систему маркировки, например, для Честного ЗНАКа, то коды не генерируются произвольно, а получаются от оператора системы маркировки или от поставщика, и они уже являются уникальными для каждого экземпляра товара, что требует контроля заполнения полей маркированного товара.

Выбор хранилища для уникальных штрихкодов

Для хранения штрихкодов в 1С мы можем рассмотреть несколько вариантов:

  1. Регистр сведений "ШтрихкодыНоменклатуры": Это стандартный регистр, который присутствует во многих типовых конфигурациях. Его базовая структура часто предполагает хранение штрихкода для номенклатуры и ее характеристики. Для поштучного учета нам потребуется расширить его измерениями, чтобы привязать штрихкод к конкретному экземпляру, или использовать его немного иначе, генерируя новый штрихкод для каждой "единицы" товара, даже если номенклатура одна и та же.
  2. Механизм серийных номеров: В более продвинутых конфигурациях, таких как "Управление торговлей" (УТ) или "ERP Управление предприятием", существует полноценный механизм учета товаров по серийным номерам. В этом случае уникальный штрихкод может быть привязан к конкретному серийному номеру, который уже уникально идентифицирует экземпляр.
  3. Справочник "ШтрихкодыУпаковокТоваров": Также в УТ и ERP есть этот справочник, предназначенный для хранения штрихкодов, связанных с упаковками или индивидуальными экземплярами товаров. Он позволяет привязать штрихкод к серийному номеру или другому уникальному идентификатору экземпляра номенклатуры, что является идеальным решением для маркированного товара или товаров, требующих поштучного учета.
  4. Дополнительные реквизиты или специализированные регистры: Если типовые механизмы по какой-то причине не подходят (например, мы работаем в "Бухгалтерии Предприятия" и не хотим ее сильно дорабатывать), мы можем создать собственный регистр сведений. Этот регистр должен будет хранить связь между сгенерированным уникальным штрихкодом и конкретным экземпляром номенклатуры (например, через ссылку на документ оприходования, номер строки в нем и/или уникальный идентификатор экземпляра).

В нашем случае, когда автор работает с "Бухгалтерией Предприятия" (БП), самый простой путь — это адаптация регистра "ШтрихкодыНоменклатуры" или создание собственного. Для более сложных задач и полноценного управленческого учета, мы бы рекомендовали использование УТ или ERP с их встроенными механизмами.

Реализация генерации штрихкодов: пошаговая инструкция

Мы рассмотрим вариант реализации, который подходит для "учебной задачи" в "Бухгалтерии Предприятия", используя регистр сведений ШтрихкодыНоменклатуры и генерацию уникальных GUID в качестве штрихкодов.

Шаг 1: Подготовка (Место для кода)

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

Шаг 2: Модификация регистра сведений (при необходимости)

Если мы хотим хранить действительно уникальные штрихкоды для каждой единицы товара в РегистреСведений.ШтрихкодыНоменклатуры, нам может потребоваться убедиться, что измерения регистра не препятствуют этому. Например, если измерениями являются только Номенклатура и Характеристика, то для одной комбинации мы сможем записать только один штрихкод. В таком случае нам нужно будет либо расширить измерения (например, добавить измерение "ИдентификаторЭкземпляра"), либо использовать поле штрихкода как "ресурс" и генерировать записи с повторяющимися измерениями (что возможно, но нетипично для регистров сведений, где измерения обычно формируют ключ уникальности записи). Однако, если мы просто генерируем уникальный штрихкод для каждой единицы и не используем стандартную логику поиска по Номенклатура+Характеристика, мы можем просто создавать записи с уникальным полем "Штрихкод".

Шаг 3: Алгоритм генерации штрихкодов для каждой единицы

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

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


// Пример кода, который мы разместим, например, в модуле объекта документа "ПоступлениеТоваровИУслуг"
// в обработчике события "ОбработкаПроведения" или "ПриЗаписи"

// Предположим, что в табличной части "Товары" есть колонки "Номенклатура", "Характеристика", "Количество".

Процедура СгенерироватьУникальныеШтрихкодыДляПоступления(ОбъектДокумента)
    
    // Создадим временную таблицу для сбора данных о номенклатуре,
    // чтобы избежать запросов в цикле и подготовить данные для пакетной записи.
    ТаблицаДляГенерации = Новый ТаблицаЗначений;
    ТаблицаДляГенерации.Колонки.Добавить("Номенклатура");
    ТаблицаДляГенерации.Колонки.Добавить("Характеристика");
    ТаблицаДляГенерации.Колонки.Добавить("Упаковка"); // Если есть
    ТаблицаДляГенерации.Колонки.Добавить("Количество");
    
    Для Каждого СтрокаТЧ Из ОбъектДокумента.Товары Цикл
        Если НЕ ЗначениеЗаполнено(СтрокаТЧ.Номенклатура) Тогда
            Продолжить;
        КонецЕсли;
        
        // Добавляем запись для каждой строки ТЧ
        НоваяСтрока = ТаблицаДляГенерации.Добавить();
        НоваяСтрока.Номенклатура = СтрокаТЧ.Номенклатура;
        НоваяСтрова.Характеристика = СтрокаТЧ.Характеристика;
        НоваяСтрока.Упаковка = СтрокаТЧ.Упаковка;
        НоваяСтрока.Количество = СтрокаТЧ.Количество;
    КонецЦикла;
    
    // Если таблица пустая, то генерировать нечего
    Если ТаблицаДляГенерации.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    // Создаем коллекцию записей регистра для пакетной записи
    НаборЗаписейШтрихкодов = РегистрыСведений.ШтрихкодыНоменклатуры.СоздатьНаборЗаписей();
    
    Для Каждого СтрокаГенерации Из ТаблицаДляГенерации Цикл
        
        // Мы хотим сгенерировать штрихкод для каждой единицы товара.
        // Поэтому делаем цикл по количеству.
        Для Индекс = 1 По СтрокаГенерации.Количество Цикл
            
            // Создаем менеджер записи для новой записи регистра
            ТекЗаписьШтрихкода = НаборЗаписейШтрихкодов.Добавить();
            
            ТекЗаписьШтрихкода.Номенклатура = СтрокаГенерации.Номенклатура;
            ТекЗаписьШтрихкода.Характеристика = СтрокаГенерации.Характеристика;
            ТекЗаписьШтрихкода.Упаковка = СтрокаГенерации.Упаковка;
            
            // Генерируем уникальный штрихкод как строку из GUID
            // Это обеспечит уникальность для каждой единицы
            ТекЗаписьШтрихкода.Штрихкод = Строка(Новый УникальныйИдентификатор());
            
            // Если в регистре есть другие измерения, например, "ТипШтрихкода",
            // устанавливаем их соответствующим образом (например, "Внутренний")
            // ТекЗаписьШтрихкода.ТипШтрихкода = Перечисления.ТипыШтрихкодов.Внутренний;
            
        КонецЦикла;
    КонецЦикла;
    
    // Записываем весь набор записей в регистр за одну операцию для оптимизации
    НаборЗаписейШтрихкодов.Записать();
    
    Сообщить("Уникальные штрихкоды для поступивших товаров успешно сгенерированы.");
    
КонецПроцедуры

// Пример вызова в обработчике проведения документа
// Процедура ОбработкаПроведения(Отказ, РежимПроведения)
//     // ... ваш код проведения документа ...
//     Если Не Отказ Тогда
//         СгенерироватьУникальныеШтрихкодыДляПоступления(ЭтотОбъект);
//     КонецЕсли;
// КонецПроцедуры

Пояснения к коду:

Шаг 4: Поиск номенклатуры по уникальному штрихкоду

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

Логика поиска, включая сканирование штрихкодов в форме подбора, будет выглядеть следующим образом:

  1. Сканируем штрихкод.
  2. Выполняем запрос к РегистрСведений.ШтрихкодыНоменклатуры, чтобы найти запись по этому штрихкоду.
  3. Из найденной записи получаем ссылки на Номенклатура, Характеристика и, возможно, другие данные, которые нам необходимы.

// Пример функции для поиска номенклатуры по штрихкоду
Функция НайтиНоменклатуруПоШтрихкоду(Знач ШтрихкодДляПоиска)
    
    Если НЕ ЗначениеЗаполнено(ШтрихкодДляПоиска) Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |    ШтрихкодыНоменклатуры.Номенклатура КАК Номенклатура,
    |    ШтрихкодыНоменклатуры.Характеристика КАК Характеристика,
    |    ШтрихкодыНоменклатуры.Упаковка КАК Упаковка
    |ИЗ
    |    РегистрСведений.ШтрихкодыНоменклатуры КАК ШтрихкодыНоменклатуры
    |ГДЕ
    |    ШтрихкодыНоменклатуры.Штрихкод = &Штрихкод";
    
    Запрос.УстановитьПараметр("Штрихкод", ШтрихкодДляПоиска);
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    Если Выборка.Следующий() Тогда
        // Возвращаем структуру или просто Номенклатуру, в зависимости от потребностей
        Возврат Новый Структура("Номенклатура, Характеристика, Упаковка", 
                                Выборка.Номенклатура, Выборка.Характеристика, Выборка.Упаковка);
    Иначе
        Возврат Неопределено;
    КонецЕсли;
    
КонецФункции

// Пример использования
// НайденныеДанные = НайтиНоменклатуруПоШтрихкоду("ваш уникальный штрихкод");
// Если НайденныеДанные <> Неопределено Тогда
//     Сообщить("Найдена номенклатура: " + НайденныеДанные.Номенклатура + 
//              " (Характеристика: " + НайденныеДанные.Характеристика + ")");
// Иначе
//     Сообщить("Штрихкод не найден.");
// КонецЕсли;

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

Использование стандартных механизмов 1С для поштучного учета

Хотя предложенный выше вариант с GUID и регистром сведений ШтрихкодыНоменклатуры является рабочим для "учебной задачи" и может быть реализован в "Бухгалтерии Предприятия", для более сложного и полноценного поштучного учета, особенно в торговых и производственных компаниях, мы настоятельно рекомендуем рассмотреть специализированные конфигурации 1С.

Учет по серийным номерам в 1С:Управление торговлей и 1С:ERP Управление предприятием

В конфигурациях 1С:Управление торговлей (УТ) и 1С:ERP Управление предприятием предусмотрен мощный механизм учета по серийным номерам. Принцип работы следующий:

  1. Для номенклатуры, которую мы хотим учитывать поштучно, мы устанавливаем вид учета запасов с использованием серийных номеров.
  2. При поступлении (оприходовании) товара мы указываем или генерируем серийные номера для каждой единицы. Каждый серийный номер является уникальным идентификатором экземпляра товара.
  3. Штрихкод может быть привязан непосредственно к серийному номеру. То есть, когда мы сканируем штрихкод, система ищет не просто номенклатуру, а конкретный серийный номер.

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

Справочник "ШтрихкодыУпаковокТоваров"

В УТ и ERP также существует справочник ШтрихкодыУпаковокТоваров. Он предназначен для хранения штрихкодов, которые могут быть привязаны к:

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

Если мы решаем задачу для УТ или ERP, нам следует изучить функциональность этого справочника и соответствующие модули, которые управляют его заполнением при поступлении и использованием при отгрузках.

Оптимизация производительности при генерации большого количества штрихкодов

Когда мы работаем с документами, содержащими сотни или тысячи строк, и для каждой строки необходимо генерировать множество штрихкодов (например, 3000 строк по 10 штук каждая = 30 000 штрихкодов), производительность становится критически важной. Вот несколько правил, которые мы должны соблюдать:

  1. Избегайте запросов и обращений к базе данных в цикле: Как мы уже видели в примере, сначала мы собираем все необходимые данные из табличной части документа во временную таблицу в памяти, а затем уже работаем с этой таблицей. Запрос к базе данных (как в коде сообщения 2) для каждой строки табличной части документа будет очень медленным.
  2. Используйте пакетную запись: Всегда предпочтительнее собрать все изменения в наборы записей регистров и записать их в базу данных одной операцией (например, НаборЗаписей.Записать()), чем записывать каждую запись по отдельности в цикле. Это существенно снижает количество обращений к базе данных.
  3. Фоновые задания: Для очень больших объемов генерации штрихкодов или других длительных операций, мы можем рассмотреть выполнение этой логики в фоновом задании. Это позволит пользователю продолжить работу с программой, пока операция выполняется на сервере в фоновом режиме.
  4. Минимизируйте объем обрабатываемых данных: Запрашивайте и обрабатывайте только те данные, которые абсолютно необходимы.

Печать уникальных этикеток

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

  1. Создать или доработать макет печатной формы, которая будет выводить индивидуальный штрихкод (например, в формате Code 128, Data Matrix или QR-код).
  2. Обеспечить передачу на форму печати не только номенклатуры, но и соответствующего уникального штрихкода для каждой единицы.

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

Роль БСП (Библиотеки стандартных подсистем)

Библиотека стандартных подсистем (БСП) предоставляет множество общих функций, включая базовые механизмы работы со штрихкодами (например, для формирования контрольной суммы EAN13 или работы с общими справочниками штрихкодов). Однако для специфического и сложного поштучного учета, где каждый экземпляр товара требует уникального штрихкода, БСП, как правило, не предоставляет готового "из коробки" решения. Модули БСП, такие как "УправлениеШтрихкодами", могут быть полезны для базовых операций и создания общих форм, но логика уникальной идентификации каждого экземпляра товара обычно требует более глубокой настройки или доработки в рамках конкретной конфигурации (или использования встроенных механизмов УТ/ERP).

Заключение

Мы рассмотрели различные подходы к генерации уникальных штрихкодов для каждой единицы номенклатуры при оприходовании. Для простых "учебных задач" в конфигурациях вроде "Бухгалтерии Предприятия" мы можем реализовать собственную логику с использованием уникальных идентификаторов (GUID) и регистра сведений ШтрихкодыНоменклатуры, применяя при этом принципы оптимизации производительности.

Для более продвинутого и надежного поштучного учета в реальных бизнес-процессах, особенно в сфере торговли или производства, нам целесообразно использовать специализированные конфигурации 1С, такие как "Управление торговлей" или "ERP Управление предприятием". Эти системы предлагают встроенные механизмы учета по серийным номерам и справочник ШтрихкодыУпаковокТоваров, которые оптимально подходят для решения подобных задач и обеспечивают более полную функциональность для управления запасами по экземплярам.

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

← На главную