Молочников Олег Spb. 2010.
Стандартные доработки. Штрихкодирование документов.
Эта статья описывает процесс доработки типовых 1С конфигураций, для добавления функционала штрихкодирования документов и быстрого их поиска по штрихкоду. Метод работает для управляемых и неуправляемых печатных форм.
В этом примере рассматривается генерация штрихкода EAN128 следующей структуры: 3 символа – для идентификации типа документа + 6 символов для даты + номер документа. Из ограничений метода : в области макета где печатается штрихкод возможна печать только одного штрихкода. Название рисунка для штрихкода должно начинаться на «Штрихкод”. Метод не работает без изменений, если есть кириллические символы в префиксах документах.
1. В общий модуль, выполняемый на сервере добавьте следующие функции:
Функция ПодключитьВнешнююКомпонентуПечатиШтрихкода() Экспорт
// В зависимости от типа платформы подключим соответствующую внешнюю компоненту
ПодключениеВыполнено = Неопределено;
СистемнаяИнформация = Новый СистемнаяИнформация;
Если СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86 Тогда
ПодключениеВыполнено = ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаПечатиШтрихкодовWindows32", "КартинкаШтрихкода", ТипВнешнейКомпоненты.Native);
ИначеЕсли СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64 Тогда
ПодключениеВыполнено = ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаПечатиШтрихкодовWindows64", "КартинкаШтрихкода", ТипВнешнейКомпоненты.Native);
ИначеЕсли СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Linux_x86 Тогда
ПодключениеВыполнено = ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаПечатиШтрихкодовLinux32", "КартинкаШтрихкода", ТипВнешнейКомпоненты.Native);
Иначе
ПодключениеВыполнено = ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаПечатиШтрихкодовLinux64", "КартинкаШтрихкода", ТипВнешнейКомпоненты.Native);
КонецЕсли;
// Создадим объект внешней компоненты
Если ПодключениеВыполнено Тогда
ВнешняяКомпонента = Новый("AddIn.КартинкаШтрихкода.Barcode");
Иначе
Возврат Неопределено;
КонецЕсли;
// Если нет возможности рисовать
Если НЕ ВнешняяКомпонента.ГрафикаУстановлена Тогда
// То картинку сформировать не сможем
Возврат Неопределено;
Иначе
// Установим основные параметры компоненты
// Если в системе установлен шрифт Tahoma
Если ВнешняяКомпонента.НайтиШрифт("Tahoma") Тогда
// Выбираем его как шрифт для формирования картинки
ВнешняяКомпонента.Шрифт = "Tahoma";
Иначе
// Шрифт Tahoma в системе отсутствует
// Обойдем все доступные компоненте шрифты
Для Сч = 0 По ВнешняяКомпонента.КоличествоШрифтов -1 Цикл
// Получим очередной шрифт, доступный компоненте
ТекущийШрифт = ВнешняяКомпонента.ШрифтПоИндексу(Сч);
// Если шрифт доступен
Если ТекущийШрифт <> Неопределено Тогда
// Они и будет шрифтом для формирования штри-кода
ВнешняяКомпонента.Шрифт = ТекущийШрифт;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
// Утановим размер шрифта
ВнешняяКомпонента.РазмерШрифта = 12;
Возврат ВнешняяКомпонента;
КонецЕсли;
КонецФункции
// Функция выполняет формирование изображения штрихкода.
//
// Параметры:
// ТипКода число от 0 до 16
// EAN8, EAN13, EAN128, Code39, Code128, Code16k, PDF417, Standart (Industrial) 2 of 5, Interleaved 2 of 5, Расширение Code39, Code93, ITF14, RSS14, CodaBar, EAN13 AddOn 2, EAN13 AddOn 5
Функция ПолучитьКартинкуШтрихкода(ВнешняяКомпонента, Ширина, Высота, Штрихкод, ТипКода = 0) Экспорт
// Зададим размер картинки
ВнешняяКомпонента.Ширина = Окр(Ширина);
ВнешняяКомпонента.Высота = Окр(Высота);
// Разрешим компоненте самой определять тип кода
ВнешняяКомпонента.АвтоТип = Ложь;
ВнешняяКомпонента.ТипКода = ТипКода;
// Если код содержит контрольный символ, обязательно указываем
ВнешняяКомпонента.СодержитКС = СтрДлина(Штрихкод) = 13;
ВнешняяКомпонента.ОтображатьТекст=Ложь;
// Если отображать контрольный символ не нужно
// ВнешняяКомпонента.ВидимостьКС = Ложь;
// Формируем картинку штрихкода
ВнешняяКомпонента.ЗначениеКода = Штрихкод;
// Если установленная нами ширина меньше минимально допустимой для этого штрихкода
Если ВнешняяКомпонента.Ширина < ВнешняяКомпонента.МинимальнаяШиринаКода Тогда
// Скорректируем ширину
ВнешняяКомпонента.Ширина = ВнешняяКомпонента.МинимальнаяШиринаКода + 10;
КонецЕсли;
// Сформируем картинку
ДвоичныеДанныеКартинки = ВнешняяКомпонента.ПолучитьШтрихкод();
// Если картинка сформировалась
Если ДвоичныеДанныеКартинки <> Неопределено Тогда
// Формируем из двоичных данных
Возврат Новый Картинка(ДвоичныеДанныеКартинки);
КонецЕсли;
Возврат Неопределено;
КонецФункции
Функция ВывестиШтрихкодДокументаВОбластьМакета(ВнешняяКомпонента,ОбластьМакета,ЗначениеШтрихкода) Экспорт
Для каждого Рисунок Из ОбластьМакета.Рисунки Цикл
Если Лев(Рисунок.Имя,8) = "Штрихкод" Тогда
Если ВнешняяКомпонента = Неопределено Тогда
ВызватьИсключение НСтр("ru = 'Ошибка подключения внешней компоненты печати штрихкода!'");
КонецЕсли;
Если ЗначениеЗаполнено(ЗначениеШтрихкода) Тогда
Рисунок.Картинка = ПолучитьКартинкуШтрихкода(ВнешняяКомпонента, 361, 50, ЗначениеШтрихкода, 3);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецФункции
2. Проверим наличие в общих макетах компонент: КомпонентаПечатиШтрихкодовWindows32, КомпонентаПечатиШтрихкодовWindows64, КомпонентаПечатиШтрихкодовLinux32, КомпонентаПечатиШтрихкодовLinux64
Если их там нет, возьмем из типовых конфигураций.
3. Модифицируем печатные формы документов следующим образом: Добавим на печатные формы требуемых документов изображение штрихкода как на рисунке с примером макета.
Обязательно имя рисунка должно начинаться на «Штрихкод”!!!!
4. В тело функции печати печатной формы добавляем:
В начало функции:
ВнешняяКомпонента = ИМЯОБЩЕГОМОДУЛЯ.ПодключитьВнешнююКомпонентуПечатиШтрихкода();
Перед выводом макета области со штрихкодом:
ИМЯОБЩЕГОМОДУЛЯ.ВывестиШтрихкодДокументаВОбластьМакета(ВнешняяКомпонента,ОбластьМакета,"PER"+СтрЗаменить(Формат(Шапка.Дата,"ДФ=dd.MM.yy"),".","")+Шапка.Номер);
"PER» - заменяем на уникальное обозначение типа печатаемого документа. (В моем случае, это перемещение).
5. В обработку ТОСервер в модуль объекта в тело функции “ОбработатьСобытиеСШК» вставляете следующий код:
Если СтрДлина(ШК)=20 Тогда
Попытка
Если Лев(ШК,3)="RTU" Тогда
ТипДокумента="РеализацияТоваровУслуг";
ИначеЕсли Лев(ШК,3)="PTU" Тогда
ТипДокумента="ПоступлениеТоваровУслуг";
ИначеЕсли Лев(ШК,3)="PER" Тогда
ТипДокумента="ПеремещениеТоваров";
Иначе
Обработка.СобытиеОбработано(Объект);
Возврат Результат;
КонецЕсли;
Дата=Дата(2000+Число(Сред(ШК,8,2)), //Год
Число(Сред(ШК,6,2)), //Месяц
Число(Сред(ШК,4,2))); //День
НомерДок=Сред(ШК,10);
Результат = Документы[ТипДокумента].НайтиПоНомеру(НомерДок, Дата);
Если Результат.Пустая() Тогда
Предупреждение("Документ не найден!");
Иначе
Результат.ПолучитьФорму().Открыть();
КонецЕсли;
Обработка.СобытиеОбработано(Объект);
Возврат Результат;
Исключение
Обработка.СобытиеОбработано(Объект);
Возврат Результат;
КонецПопытки;
КонецЕсли;
6. Дальнейшее развитие идеи (по комментариям читателей):
А) Вместо привязки к номеру, дате и типу документа можно использовать уникальный идентификатор документа. Это более универсальный метод.
Б) Если печатных форм много, то можно не менять макеты печатных форм, а сделать механизм хранения координат места в макете, в котором создавать динамический рисунок и в него выводить штрихкод. Требует экспериментов, но выигрыш в реализации очевиден: минимизация изменений конфигурации, простота добавления штрихкодов.
PS:Заранее благодарен за любые замечания и исправления.