Как перехватить номер документа и сформировать штрихкод перед записью в 1С:Бухгалтерия 3.0

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

В процессе разработки в среде 1С:Предприятие 8.3, особенно в конфигурации 1С:Бухгалтерия предприятия 3.0, часто возникает задача автоматической генерации штрихкода для документа. Типичный сценарий: штрихкод должен содержать номер документа и год, либо уникальный идентификатор. Основная сложность заключается в том, что в момент создания нового документа его номер еще не присвоен платформой, а УникальныйИдентификатор ссылки может быть не определен до момента физической записи в базу данных. В этой статье мы подробно разберем, где именно нужно «перехватывать» управление, чтобы получить номер, и какие стратегии формирования штрихкодов наиболее эффективны.

Метод 1: Использование события ПриУстановкеНомера

Разберем стандартный механизм платформы. По умолчанию номер документа формируется в самом конце транзакции записи. Если мы попытаемся прочитать реквизит Номер в процедуре ПередЗаписью, мы увидим пустую строку (для нового объекта). Чтобы вмешаться в процесс генерации номера, нам необходимо использовать обработчик события ПриУстановкеНомера.

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

Рассмотрим пример кода в модуле объекта документа:


Процедура ПриУстановкеНомера(СтандартнаяОбработка, Префикс)
    // Здесь платформа уже определила префикс, но номер еще может быть не окончательным
    // Если нужно программно повлиять на номер:
    // Префикс = "МТ-" + Префикс;
КонецПроцедуры

Однако стоит учитывать, что в Бухгалтерии 3.0 большинство механизмов префиксации вынесено в подписки на события. Поэтому наиболее правильным методом будет создание собственной Подписки на событие ПриУстановкеНомера. Это позволит не снимать документ с поддержки и гарантированно получить номер сразу после того, как БСП (Библиотека стандартных подсистем) сформирует все префиксы организации и подразделения.

Метод 2: Принудительная установка номера в ПередЗаписью

Если нам критически важно записать штрихкод (Номер + Год) непосредственно в реквизит документа перед тем, как данные попадут в таблицу базы данных, мы можем принудительно инициировать установку номера. Выясним, как это сделать правильно в процедуре ПередЗаписью.

Мы можем использовать метод УстановитьНовыйНомер(). Это заставит платформу сгенерировать номер немедленно. После этого мы можем сформировать строку штрихкода и заполнить соответствующий реквизит.


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

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

Метод 3: Использование ГУИД документа для штрихкодирования

Как отмечалось в обсуждении на форуме, использование номера документа в штрихкоде имеет существенный недостаток: если бухгалтер изменит номер или дату (переместив документ в другой год), штрихкод на распечатанном листе перестанет соответствовать данным в базе. Чтобы избежать этой проблемы, профессионалы рекомендуют использовать УникальныйИдентификатор (GUID) ссылки документа.

Многие начинающие разработчики полагают, что ГУИД появляется только после записи. Но это не так. Мы можем получить ссылку для нового документа еще до его первой записи. Посмотрим на пример получения ссылки в модуле формы или при создании объекта:


// Пример получения будущей ссылки нового документа
НоваяСсылка = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(Новый УникальныйИдентификатор());
ЭтотОбъект.УстановитьСсылкуНового(НоваяСсылка);

// Теперь НоваяСсылка.УникальныйИдентификатор() доступен для генерации ШК
МойШтрихкод = Строка(НоваяСсылка.УникальныйИдентификатор());

Проанализируем ситуацию с длиной кода. Полный ГУИД — это 36 символов. Для линейного штрихкода типа EAN-13 он не подходит, а для Code 128 он будет слишком длинным (штрихкод получится очень «широким», что затруднит чтение обычным сканером). В таких случаях рекомендуется использовать преобразование ГУИД в строку Base64 или использовать QR-коды.

Метод 4: Хранение штрихкодов в независимом регистре

Вместо того чтобы добавлять реквизит Штрихкод в каждый документ, что увеличивает размер таблиц и усложняет поддержку, рассмотрим архитектурно более верное решение — использование регистра сведений. В 1С:БСП для этого часто используется регистр Штрихкоды или создается аналогичный пользовательский (например, ДопШтрихкодыОбъектов).

Пошаговый алгоритм реализации:

  1. Создаем независимый регистр сведений ШтрихкодыОбъектов с измерениями Владелец (Тип: ЛюбаяСсылка) и ресурсом Штрихкод (Тип: Строка).
  2. В подписке на событие ПриЗаписи документа проверяем, есть ли уже запись в регистре для данного объекта.
  3. Если записи нет — генерируем код (на основе ID или номера) и записываем в регистр.
  4. При печати документа берем значение штрихкода из регистра, выполняя простой запрос.

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

Работа с механизмами БСП для печати штрихкодов

Поскольку Бухгалтерия предприятия 3.0 базируется на БСП, нам не нужно «изобретать велосипед» для визуализации кода. В конфигурации уже есть общие модули для работы с компонентой печати. Разберем, как вывести штрихкод в печатную форму, не сохраняя его картинку в базе:

Для формирования изображения используется компонента 1С:Печать штрихкодов. В макете печатной формы создается область с рисунком (тип «Объект»), а в коде обработки печати вызывается функция, которая передает строку штрихкода компоненте и получает готовую картинку для вывода в табличный документ.


// Примерный алгоритм в модуле менеджера (печать)
МенеджерПечати = ОбщегоНазначения.МенеджерОборудованияКлиентСервер();
ПараметрыШтрихкода = Новый Структура;
ПараметрыШтрихкода.Вставить("Ширина", 100);
ПараметрыШтрихкода.Вставить("Высота", 30);
ПараметрыШтрихкода.Вставить("ТипКода", 4); // Code128

КартинкаШтрихкода = МенеджерПечати.СформироватьИзображениеШтрихкода(ТекстШтрихкода, ПараметрыШтрихкода);
ОбластьМакета.Рисунки.Штрихкод.Картинка = КартинкаШтрихкода;

Подведение итогов

Выясним причины, по которым тот или иной метод может быть предпочтительнее. Если ваша задача — строгая отчетность и поиск документа по «красивому» номеру (например, 000001-2023), то используйте Метод 2 с принудительной установкой номера в ПередЗаписью. Если же ваша цель — надежная автоматизация склада или архива, где штрихкод не должен меняться никогда, используйте Метод 3 (ГУИД документа) в связке с Методом 4 (регистр сведений).

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

← На главную