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