gifts2017

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

Опубликовал Roman Bobreshov (BobreshovR) в раздел Программирование - Практика программирования

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

Итак, мы имеем типовую БП 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);

 

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

  

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

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Обработка печати этикеток
.epf 25,41Kb
18.02.13
116
.epf 25,41Kb 116 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Константин (maverick76) 19.02.13 11:47
Думаю может пригодиться
2. Yura Yura (YuraLu) 20.02.13 09:05
Однозначно - плюс. В копилку полезностей!!!
3. Pavel Korolev (Korolev) 20.02.13 09:33
Интересно, может понадобится в будущем.
4. Макас (makas) 20.02.13 12:23
Подскажите, что надо сделать чтобы печатать этикетки к:

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

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

-----------
В остальном, плюс за поленую работу!
5. Roman Bobreshov (BobreshovR) 20.02.13 13:35
Заполнить ТЧ обработки или просто вывести эти реквизиты на этикетку?
6. Макас (makas) 20.02.13 14:05
(5) просто вывести на печать штрихкод Товара с артикулом или ОС с Номером
7. Roman Bobreshov (BobreshovR) 20.02.13 15:00
(6) makas, все просто нужно в макете добавить эти параметры, артикул номенклатуры можно поставить после номера или вообще вместо, а при вызове функций печати нужно просто присвоить эти параметры, если хотите добавить новые строки тогда обратитесь к статье там написано как нужно рассчитывать высоты строк и так же описано какие области есть и зачем они нужны
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа