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