Печать этикеток со штрих-кодами для БП 2.0


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

Итак, мы имеем типовую БП 2.0 и нам нужно реализовать печать этикеток со штрих-кодами для номенклатуры и ОС (Основные средства). В типовой БП механизм печати штрих-кодов не предусмотрен, поэтому начнем с создания данного механизма.

Сначала заведем регистр сведений для хранения штрих-кодов «ШтрихкодыНоменклатурыИОС». В регистре будет одно измерение «Объект» (составного типа: СправочникСсылка.ОС, СправочникСсылка.Номенклатура) и ресурс Штрихкод (тип Число).

Встает вопрос, как реализовать уникальность штрих-кодов в базе и контрольную цифру (используем EAN13). Рассмотрим следующий механизм: запретим пользователям интерактивный доступ к регистру, и  при добавлении нового штрих-кода будем присваивать ему значение, равное количеству записей в регистре плюс один. Тем самым сохраним уникальность штрих-кодов в пределах базы. Контрольный символ будем рассчитывать при самой печати.

Далее, пишем обработку печати этикеток (самым оптимальным видом обработки считается типовой, реализованный в УТ и Рознице, поэтому будем создавать нашу обработку по аналогии с ней). Наша обработка будет выглядеть следующим образом: пользователь выбирает сначала, какую этикетку он собирается вывести на печать: для ОС или Номенклатуры, — и в зависимости от этого будут работать различные механизмы заполнения. Также, в шапке формы укажем количество этикеток по горизонтали и вертикали на странице и отступ между ними (к ним мы еще вернемся), и отступы на странице. Реализация обработки заполнения может быть в принципе любая, какую захочет пользователь. Вот один из примеров:

Перезаполнить = Ложь;
Режим = РежимДиалогаВопрос.ДаНет;
Ответ = Вопрос("Перезаполнить таблицу?",Режим);
Перезаполнить = Ответ = КодВозвратаДиалога.Да;


Если ФлагЭтикетки Тогда

ФормаВыбора =  Документы.ИнвентаризацияОС.ПолучитьФормуВыбора();
Инвертеризация = ФормаВыбора.ОткрытьМодально();
Если Инвертеризация = Неопределено Тогда
Возврат
КонецЕсли;

Запрос = новый запрос;
Запрос.Текст =  "ВЫБРАТЬ
|              ИнвентаризацияОСОС.ОсновноеСредство,
|              ИнвентаризацияОСОС.НаличиеПоДаннымУчета КАК Количество,
|              ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.ИнвентарныйНомер,
|              ИнвентаризацияОСОС.Ссылка.Организация,
|              ИнвентаризацияОСОС.Ссылка.ПодразделениеОрганизации КАК Подразделение
|ИЗ
|              Документ.ИнвентаризацияОС.ОС КАК ИнвентаризацияОСОС
|                              ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПервоначальныеСведенияОСБухгалтерскийУчет.СрезПоследних КАК ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних
|                              ПО ИнвентаризацияОСОС.ОсновноеСредство = ПервоначальныеСведенияОСБухгалтерскийУчетСрезПоследних.ОсновноеСредство
|ГДЕ
|              ИнвентаризацияОСОС.Ссылка = &Инвертеризация";
Запрос.УстановитьПараметр("Инвертеризация",Инвертеризация);


иначе

ФормаВыбора = Документы.ИнвентаризацияТоваровНаСкладе.ПолучитьФормуВыбора();
Инвертеризация = ФормаВыбора.ОткрытьМодально();
Если Инвертеризация = Неопределено Тогда
Возврат
КонецЕсли;


Запрос = новый запрос;
Запрос.Текст =  "ВЫБРАТЬ
|              ИнвентаризацияТоваровНаСкладеТовары.КоличествоУчет КАК Количество,
|              ИнвентаризацияТоваровНаСкладеТовары.Номенклатура как ОсновноеСредство,
|   0 как ИнвентарныйНомер,
|   NULL как Организация,
|   NULL как Подразделение
|ИЗ
|              Документ.ИнвентаризацияТоваровНаСкладе.Товары КАК ИнвентаризацияТоваровНаСкладеТовары
|ГДЕ
|              ИнвентаризацияТоваровНаСкладеТовары.Ссылка = &Инветаризация";
Запрос.УстановитьПараметр("Инветаризация",Инвертеризация);

КонецЕсли;

Выборка = Запрос.Выполнить().Выбрать();
пока Выборка.Следующий() Цикл

Строка = ОС.Добавить();
Строка.ОсновноеСредство = Выборка.ОсновноеСредство;
Строка.Печать = Истина;
Строка.Количество = Выборка.Количество;
Строка.ИнвентарныйНомер = Выборка.ИнвентарныйНомер;
Строка.Организация    = Выборка.Организация;
Строка.Подразделение  = Выборка.Подразделение;

КонецЦикла;

 

Здесь заполнение производится на основании инвентаризации, никаких сложностей (и ничего интересногоSmile)

 

 

Переходим к самой печати этикетки. Не знаю, какая система измерения в макетах для 1С используется, но нечеловеческая это точноSmile. Согласно моему ТЗ,  заказчик подразумевал размер этикетки 64,6х33,8мм. Как его реализовать в макетах? Дело оказалось намного запутанней, чем я мог себе предположить. Но по порядку. Сначала необходимо реализовать макет. В макете сделаем нашу этикетку  как нам удобно (размеры не важны). Лично я использовал для этикетки 3 столбца и 6 строк (для номенклатуры, для ОС несколько больше). И присвоим нашей этикетки область «Этикетка», также создадим 3 области: горизонтальный разрыв (целая строка), вертикальный разрыв (Столбец из 6 строк) и разрыв страницы (с заданным на нем разрывом страницы), и еще три последние строки этикетки отдадим под штрихкод, и создадим в них область «ОбластьШтрихКода» (Мы еще ее помучаем).

Переходим к непосредственной реализации печати:

 

ТабДок = новый ТабличныйДокумент;
Если ФлагЭтикетки Тогда

Макет = ЭтотОбъект.ПолучитьМакет("МакетОС");
ОбластьВертРазрыв = Макет.ПолучитьОбласть("ВертикальныйРазрыв");
ОбластьСтрРазрыв = Макет.ПолучитьОбласть("РазрывСтраницы");
ОблстьГоризРазрыв = Макет.ПолучитьОбласть("ГоризонтальныйРазрыв");
ОбластьВертРазрыв.Области.ВертикальныйРазрыв.ШиринаКолонки = 0.505*ОтступМеждуЭтикеткамиВертикаль;

ОблстьГоризРазрыв.Области.ГоризонтальныйРазрыв.ВысотаСтроки = 2.65*ОтступМеждуЭтикеткамиГоризонтали;

 

 

Здесь вот одна особенность: значению ОбластьВертРазрыв.Области.ВертикальныйРазрыв.ШиринаКолонки  мы присваиваем отступ между этикетками по вертикали, умноженный на число 0.505. Это многострадальное число и его собрат 2.65 —  коэффициенты пересчета для ширины колонки и высоты колонки для макетов в 1С. В результате получаем миллиметры. Продолжим:

 

ЭтикетокВСтроке = 0;
СтрокНаСтранице = 1;

Для каждого строка Из ЭтотОбъект.ОС Цикл

Если Строка.Печать Тогда

Для Счетчик = 1 По Строка.Количество Цикл


ОбластьЭтикетка =  Макет.ПолучитьОбласть("Этикетка");


ОбластьЭтикетка.Области.Этикетка.ВысотаСтроки = 5.1*2.65;                     //Коэфициент для высоты строки 2.65;
ОбластьЭтикетка.Области.Этикетка.ШиринаКолонки = 22.23*0.505;                                                                       //Коэфициент для ширины колонки 0,505;

ОбластьЭтикетка.Параметры.Наименование = Строка.ОсновноеСредство.Наименование;
ОбластьЭтикетка.Параметры.Номер = Строка.ИнвентарныйНомер;
ОбластьЭтикетка.Параметры.Организация = Строка.Организация;
ОбластьЭтикетка.Параметры.Подразделение = Строка.Подразделение;
ОбластьЭтикетка.Параметры.ЗавНомер = Строка.ОсновноеСредство.ЗаводскойНомер;
Если ЗначениеЗаполнено(Строка.ОсновноеСредство.ДатаВыпуска) Тогда
ОбластьЭтикетка.Параметры.ГодВыпуска = Год(Строка.ОсновноеСредство.ДатаВыпуска);
КонецЕсли;



Если ЭтикетокВСтроке = ЭтотОбъект.КоличествоПоГоризонтале Тогда



ТабДок.Вывести(ОблстьГоризРазрыв);


Если СтрокНаСтранице = ЭтотОбъект.КоличесвоПоВертикале Тогда

ТабДок.Вывести(ОбластьСтрРазрыв);
СтрокНаСтранице = 0;

КонецЕСли;

ТабДок.Вывести(ОбластьЭтикетка);
ЭтикетокВСтроке = 0;
СтрокНаСтранице = СтрокНаСтранице + 1;
иначе

ТабДок.Присоединить(ОбластьЭтикетка);

КонецЕсли;

ЭтикетокВСтроке = ЭтикетокВСтроке + 1;




ТабДок.Присоединить(ОбластьВертРазрыв);


КонецЦикла;

КонецЕсли;

КонецЦикла;

 

Здесь идет полная реализация печати этикеток. В качестве высоты и ширины строк и столбцов еще выступают некоторые числа: они получены простым делением общей высоты или ширины этикетки на количество столбцов или строк.

Отлично, печать идет, но чего-то не хватает, правильно, штрихкода.

Для начала нам нужно установить компоненту для вывода штрихкодов (элемент ActiveX). Компонента может идти с некоторыми конфигурациями или поставляется отдельно. Называется «1С: Печать штрихкодов», устанавливается как обычная программа. Теперь необходимо вставить штрихкод в наш макет. Выбираем  «Таблица» — «Рисунки»-«Вставить объект» и там ищем «1С: Печать штрихкодов». Вставили объект куда нужно, теперь можно его немного протестировать, в свойствах задать другой штрихкод, его тип, фон и многое другое.

            Теперь нам  необходима функция создания штрих-кода и функция поиска, а лучше все вместе где-то так:

 

Процедура КоманднаяПанель2ЗаполнитьШрихКоды(Кнопка)

для каждого Строка из ОС цикл

Если  ЗначениеЗаполнено(Строка.ОсновноеСредство) Тогда

Запрос = новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
|               ШтрихкодыНоменклатурыИОС.Объект,
|               ШтрихкодыНоменклатурыИОС.ШтрихКод
|ИЗ
|               РегистрСведений.ШтрихкодыНоменклатурыИОС КАК ШтрихкодыНоменклатурыИОС
|ГДЕ
|               ШтрихкодыНоменклатурыИОС.Объект = &Объект";
Запрос.УстановитьПараметр("Объект",Строка.ОсновноеСредство);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() ТОгда
Строка.Штрихкод = ДобавитьКонтрольныйСимвол(Выборка.ШтрихКод);
иначе
Строка.Штрихкод = ДобавитьКонтрольныйСимвол(ДобавитьШтрихКод(Строка.ОсновноеСредство));
КонецЕсли;

иначе

Сообщить("В строке "+Строка.НомерСтроки+" не заполнено ОС или номенклатура");

КонецЕсли;

КонецЦикла

КонецПроцедуры

Функция ДобавитьШтрихКод(ОбъектШтрихкода)

Запись = РегистрыСведений.ШтрихкодыНоменклатурыИОС.СоздатьМенеджерЗаписи();
Запись.Объект = ОбъектШтрихкода;
НаборЗаписей = РегистрыСведений.ШтрихкодыНоменклатурыИОС.СоздатьНаборЗаписей();
НаборЗаписей.Прочитать();

Запись.ШтрихКод = НаборЗаписей.Количество()+1;
Запись.Записать();
Возврат Запись.ШтрихКод;

КонецФункции

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

Теперь наконец-то сводим вместе наши штрихкоды и макет – это делается следующим образом:
ОбластьШтрихкод = ОбластьЭтикетка.Области.ОбластьШтрихкод;
РисунокШтрихкод = ОбластьЭтикетка.Рисунки.Штрихкод;
РисунокШтрихкод.Расположить(ОбластьШтрихкод);
ОбластьЭтикетка.Рисунки.Штрихкод.Объект.АвтоТип = Истина;
ОбластьЭтикетка.Рисунки.Штрихкод.Объект.Сообщение =Лев(строка.Штрихкод,12);

 

Здесь устанавливаем АвтоТип, чтобы компонента сама определила тип штрихкода, и передаем в компоненту сам штрихкод (что важно, передаем ее туда без контрольного символа).

  

Итак, после всех выполненных манипуляций мы получили рабочую обработку печати этикеток вместе со штрих-кодами.

13 Comments

  1. maverick76

    Думаю может пригодиться

    Reply
  2. YuraLu

    Однозначно — плюс. В копилку полезностей!!!

    Reply
  3. Korolev

    Интересно, может понадобится в будущем.

    Reply
  4. makas

    Подскажите, что надо сделать чтобы печатать этикетки к:

    1. Товары по артикулу

    2. Основным Средствам по коду,

    ————

    В остальном, плюс за поленую работу!

    Reply
  5. BobreshovR

    Заполнить ТЧ обработки или просто вывести эти реквизиты на этикетку?

    Reply
  6. makas

    (5) просто вывести на печать штрихкод Товара с артикулом или ОС с Номером

    Reply
  7. BobreshovR

    (6) makas, все просто нужно в макете добавить эти параметры, артикул номенклатуры можно поставить после номера или вообще вместо, а при вызове функций печати нужно просто присвоить эти параметры, если хотите добавить новые строки тогда обратитесь к статье там написано как нужно рассчитывать высоты строк и так же описано какие области есть и зачем они нужны

    Reply
  8. smirnova_a

    Подскажите:

    ОбластьЭтикетка.Области.Этикетка.ВысотаСтроки = 5.1*2.65; //Коэфициент для высоты строки 2.65;

    ОбластьЭтикетка.Области.Этикетка.ШиринаКолонки = 22.23*0.505;

    что за цифры: 5.1 и 22.23 соотвественно?

    Reply
  9. BobreshovR

    (9) Высота и ширина в миллиметрах, 4 года прошло. Долго играющая обработка 🙂

    Reply
  10. smirnova_a

    Получается вам нужно на все области задать такие размеры, ведь нужно итоговый размер 64,6х33,8мм.? Просто это не приведено тут в демонстрационном коде?

    Reply
  11. Zmey_72

    Было б неплохо для бух 3.0 еще сделать

    Reply
  12. BobreshovR

    (12)Сделайте 😉

    Reply
  13. Zmey_72

    а куда деваться, сделаю 😉

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *