При разработке печатных форм, таких как ценники или этикетки, программисты часто сталкиваются с неприятной особенностью внешней компоненты «1С:Печать штрихкодов». Если в объект штрихкода не передать конкретное значение или передать пустую строку, компонента автоматически выводит тестовый набор цифр, например, «123456789012» или «123456». Это портит внешний вид документа, когда у номенклатуры штрихкод просто не задан.
В этой статье мы подробно разберем все возможные способы решения этой задачи: от простых визуальных «хитростей» до правильной программной логики и современных подходов с использованием БСП.
Самый надежный и корректный способ — это управление свойством Видимость объекта в области макета. Мы проанализируем наличие данных в выборке и, если штрихкод отсутствует, просто «выключим» рисунок для данной области.
Рассмотрим пример кода, который нужно внедрить в процедуру печати:
// Получаем область из макета
ОбластьЦенника = Макет.ПолучитьОбласть("Строка");
// Проверяем наличие данных в выборке
Если ЗначениеЗаполнено(Выборка.Штрихкод) Тогда
// Если код есть, передаем его в компоненту и включаем видимость
ОбластьЦенника.Рисунки.Штрихкод.Видимость = Истина;
ОбластьЦенника.Рисунки.Штрихкод.Объект.Сообщение = Выборка.Штрихкод;
Иначе
// Если кода нет, полностью скрываем рисунок штрихкода
ОбластьЦенника.Рисунки.Штрихкод.Видимость = Ложь;
КонецЕсли;
// Выводим область в табличный документ
ТабДок.Вывести(ОбластьЦенника);
Важный нюанс: В сообщениях форума упоминалось свойство ВыводитьНаПечать. Оно также работает, но имеет особенность: объект будет виден в окне предварительного просмотра на экране, но исчезнет только при отправке на принтер. Свойство Видимость скрывает объект везде, что более предпочтительно для пользователя.
Если программное скрытие по каким-то причинам не подходит (например, сложная верстка, где скрытие объекта ломает структуру), мы можем пойти путем разделения макета. Создадим две идентичные области в макете: одну со штрихкодом, другую — без него.
Разберем алгоритм действий:
ОбластьСоШтрихкодом.ОбластьБезШтрихкода, где просто удаляем объект рисунка.
Если ЗначениеЗаполнено(Выборка.Штрихкод) Тогда
Область = Макет.ПолучитьОбласть("ОбластьСоШтрихкодом");
Область.Рисунки.Штрихкод.Объект.Сообщение = Выборка.Штрихкод;
Иначе
Область = Макет.ПолучитьОбласть("ОбластьБезШтрихкода");
КонецЕсли;
ТабДок.Вывести(Область);
Этот метод гарантирует, что макет не «поплывет», и вы точно будете знать, как выглядит печатная форма в обоих случаях.
Иногда возникают ситуации, когда компонента ведет себя непредсказуемо при попытке скрыть её. В таком случае мы можем прибегнуть к «хитрости» — сделать штрихкод невидимым, окрасив его элементы в цвет фона (белый).
Выясним причину, почему это работает: компонента отрисовывает штрихи цветом, указанным в свойстве ЦветПолос. Если этот цвет совпадает с цветом бумаги, сканер и человеческий глаз его не заметят.
Если НЕ ЗначениеЗаполнено(Выборка.Штрихкод) Тогда
// Устанавливаем белый цвет (RGB 16777215) для полос и текста
ОбластьЦенника.Рисунки.Штрихкод.Объект.ЦветПолос = 16777215;
ОбластьЦенника.Рисунки.Штрихкод.Объект.ЦветТекста = 16777215;
Иначе
// Возвращаем черный цвет для корректных данных
ОбластьЦенника.Рисунки.Штрихкод.Объект.ЦветПолос = 0;
ОбластьЦенника.Рисунки.Штрихкод.Объект.ЦветТекста = 0;
ОбластьЦенника.Рисунки.Штрихкод.Объект.Сообщение = Выборка.Штрихкод;
КонецЕсли;
Как справедливо замечено в обсуждении, проблема часто кроется в некорректной проверке данных. Если штрихкоды выбираются из регистра сведений левым соединением, в результате может оказаться NULL. Платформа 1С не всегда интерпретирует NULL как Неопределено в логических сравнениях.
Проанализируем ситуацию: использование функции ЗначениеЗаполнено() является наиболее универсальным способом, так как она возвращает Ложь для NULL, Неопределено, пустой строки и числа 0. Однако лучше всего обрабатывать пустоты еще на уровне запроса:
// В тексте запроса используем ЕСТЬNULL
"ВЫБРАТЬ
| ЕСТЬNULL(Штрихкоды.Штрихкод, """") КАК Штрихкод
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Штрихкоды КАК Штрихкоды..."
Это позволит вам всегда работать со строкой, даже если записи в регистре нет.
Если вы работаете в современной конфигурации (УТ 11, ERP 2, БП 3.0), настоятельно рекомендуем отказаться от использования ActiveX-объекта (Рисунок типа «Объект») в макете. Вместо этого используйте тип «Картинка».
Рассмотрим, как это работает через механизмы БСП (Библиотека стандартных подсистем):
Штрихкод.
Если ЗначениеЗаполнено(ДанныеШтрихкода) Тогда
ПараметрыШК = МенеджерОборудованияВызовСервера.ПараметрыГенерацииШтрихкода();
ПараметрыШК.Текст = ДанныеШтрихкода;
ПараметрыШК.ТипКода = 1; // EAN13
Результат = МенеджерОборудованияВызовСервера.СформироватьШтрихкод(ПараметрыШК);
Если Результат.Результат Тогда
Область.Рисунки.Штрихкод.Картинка = Результат.Картинка;
КонецЕсли;
Иначе
// Просто очищаем картинку или вставляем пустую
Область.Рисунки.Штрихкод.Картинка = Новый Картинка;
КонецЕсли;
Преимущества этого метода:
В редких случаях, когда удаление рисунка из коллекции (Область.Рисунки.Удалить(...)) вызывает ошибки в последующих итерациях цикла печати, можно применить метод «схлопывания» объекта.
Если НЕ ЗначениеЗаполнено(Выборка.Штрихкод) Тогда
Область.Рисунки.Штрихкод.Ширина = 0.1;
Область.Рисунки.Штрихкод.Высота = 0.1;
Иначе
// Устанавливаем стандартные размеры (например, 40х20 мм)
Область.Рисунки.Штрихкод.Ширина = 40;
Область.Рисунки.Штрихкод.Высота = 20;
Область.Рисунки.Штрихкод.Объект.Сообщение = Выборка.Штрихкод;
КонецЕсли;
Этот способ гарантирует, что объект останется в коллекции рисунков области, и обращения к нему не вызовут исключения Runtime error, при этом на листе он будет выглядеть как невидимая точка.
Мы рассмотрели различные стратегии борьбы с «фантомными» штрихкодами. Для старых систем на обычных формах лучшим выбором будет использование свойства Видимость = Ложь или переключение между двумя областями макета. Для современных систем оптимально использовать генерацию через БСП с выводом в объект типа Картинка. Выбирайте тот метод, который лучше всего вписывается в архитектуру вашего решения.