Программируя под 8.2, работающем в режиме управляемого приложения, я столкнулся с проблемой печати штрихкода. Для платформы 8.1 и платформы 8.2 в режиме обычного приложения такой проблемы не было: устанавливаем элемент «1С:Печать штрихкодов» в макет и наслаждаемся вертикальными черточками. В режиме управляемого приложения вываливается ошибка:
Код 1C v 8.2 УП ОбластьВывода.Рисунки.ШтрихКод.Объект – неопределено
Что же случилось?
Дело в том, что для управляемого приложения внешние компоненты разрабатываются по другой технологии. Пример внешней компоненты для печати штрих-кода в 8.2 есть в демонстрационной конфигурации "Управляемое приложение" в макетах справочника Товары либо в конфигурации «1С:Управление торговлей» версии 11, макеты обработки «Печать этикеток и ценников».
Данная компонента, получив в качестве параметра строку штрихкода, возвращает картинку – штрихкод, которую программисту предлагается поместить в любое удобное место печатной формы.
Теперь как это сделать.
Всего обработок аж четыре штуки:
КомпонентаПечатиШтрихкодовWindows32
КомпонентаПечатиШтрихкодовWindows64
КомпонентаПечатиШтрихкодовLinux32
КомпонентаПечатиШтрихкодовLinux64
Все они загружены в одноименные макеты. Функция, подключающая внешнюю компоненту в зависимости от платформы может выглядеть так:
Код 1C v 8.х Функция ПодключитьВнешнююКомпонентуПечатиШтрихкода() Экспорт
// В зависимости от типа платформы подключим соответствующую внешнюю компоненту
СистемнаяИнформация = Новый СистемнаяИнформация;
Если СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86 Тогда
ПодключениеВыполнено = ПодключитьВнешнююКомпоненту("Обработка.ПечатьЭтикетокИЦенников.Макет.КомпонентаПечатиШтрихкодовWindows32", "КартинкаШтрихкода", ТипВнешнейКомпоненты.Native);
ИначеЕсли СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64 Тогда
ПодключениеВыполнено = ПодключитьВнешнююКомпоненту("Обработка.ПечатьЭтикетокИЦенников.Макет.КомпонентаПечатиШтрихкодовWindows64", "КартинкаШтрихкода", ТипВнешнейКомпоненты.Native);
ИначеЕсли СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Linux_x86 Тогда
ПодключениеВыполнено = ПодключитьВнешнююКомпоненту("Обработка.ПечатьЭтикетокИЦенников.Макет.КомпонентаПечатиШтрихкодовLinux32", "КартинкаШтрихкода", ТипВнешнейКомпоненты.Native);
Иначе
ПодключениеВыполнено = ПодключитьВнешнююКомпоненту("Обработка.ПечатьЭтикетокИЦенников.Макет.КомпонентаПечатиШтрихкодовLinux64", "КартинкаШтрихкода", ТипВнешнейКомпоненты.Native);
КонецЕсли;
// Создадим объект внешней компоненты
Если ПодключениеВыполнено Тогда
ВнешняяКомпонента = Новый("AddIn.КартинкаШтрихкода.Barcode");
Иначе
Возврат Неопределено;
КонецЕсли;
// Если нет возможности рисовать
Если НЕ ВнешняяКомпонента.ГрафикаУстановлена Тогда
// То картинку сформировать не сможем
Возврат Неопределено;
Иначе
// Установим основные параметры компоненты
// Если в системе установлен шрифт Tahoma
Если ВнешняяКомпонента.НайтиШрифт("Tahoma") = Истина Тогда
// Выбираем его как шрифт для формирования картинки
ВнешняяКомпонента.Шрифт = "Tahoma";
Иначе
// Шрифт Tahoma в системе отсутствует
// Обойдем все доступные компоненте шрифты
Для Сч = 0 По ВнешняяКомпонента.КоличествоШрифтов -1 Цикл
// Получим очередной шрифт, доступный компоненте
ТекущийШрифт = ВнешняяКомпонента.ШрифтПоИндексу(Сч);
// Если шрифт доступен
Если ТекущийШрифт <> Неопределено Тогда
// Они и будет шрифтом для формирования штри-кода
ВнешняяКомпонента.Шрифт = ТекущийШрифт;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
// Утановим размер шрифта
ВнешняяКомпонента.РазмерШрифта = 10;
Возврат ВнешняяКомпонента;
КонецЕсли;
КонецФункции
В коде выше все компоненты загружены в макеты обработки «ПечатьЭтикетокИЦенников». В принципе ничто не мешает поместить их в любое иное место. Вызов функции осуществляется командой:
Код 1C v 8.х ВнешняяКомпонента = ПодключитьВнешнююКомпонентуПечатиШтрихкода();
Если что-то не получилось – возвращает НЕОПРЕДЕЛЕНО.
Далее опишем функцию, которая, получив данные, сформирует нужную нам картинку с штрихкодом:
Код 1C v 8.х Функция ПолучитьКартинкуШтрихкода(ВнешняяКомпонента, Штрихкод, Ширина, Высота) Экспорт
// Зададим размер картинки
ВнешняяКомпонента.Ширина =Ширина;
ВнешняяКомпонента.Высота =Высота;
// Разрешим компоненте самой определять тип кода
ВнешняяКомпонента.АвтоТип = истина;
// Если код содержит контрольный символ, обязательно указываем
ВнешняяКомпонента.СодержитКС = СтрДлина(Штрихкод) = 13;
// Если отображать контрольный символ не нужно
// ВнешняяКомпонента.ВидимостьКС = Ложь;
// Формируем картинку штрихкода
ВнешняяКомпонента.ЗначениеКода = Штрихкод;
// Если установленная нами ширина меньше минимально допустимой для этого штрихкода
Если ВнешняяКомпонента.Ширина < ВнешняяКомпонента.МинимальнаяШиринаКода Тогда
// Скорректируем ширину
ВнешняяКомпонента.Ширина = ВнешняяКомпонента.МинимальнаяШиринаКода + 10;
КонецЕсли;
// Сформируем картинку
ДвоичныеДанныеКартинки = ВнешняяКомпонента.ПолучитьШтрихкод();
// Если картинка сформировалась
Если ДвоичныеДанныеКартинки <> Неопределено Тогда
// Формируем из двоичных данных
Возврат Новый Картинка(ДвоичныеДанныеКартинки);
КонецЕсли;
Возврат Неопределено;
КонецФункции
В данной функции используется автоопределение типа штрихкода командой
Код 1C v 8.х ВнешняяКомпонента.АвтоТип = истина;
Можно тип штрихкода указать вручную:
Код 1C v 8.х ВнешняяКомпонента.АвтоТип = Ложь;
ВнешняяКомпонента.ТипКода = 1; // указан тип EAN13
ТипКода - число от 0 до 15: 0 - EAN8, 1 - EAN13, 2 - EAN128. Вот полный список типов по порядку:
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.
Кроме типа штрихкода, компонента имеет ряд других свойств, например ВнешняяКомпонента.ОтображатьТекст, ВнешняяКомпонента.РазмерШрифта и прочие, можно посмотреть в свойствах.
Наконец последнее - вывод штрихкода. Для этого в макет поместим картинку с именем «Штрихкод». Получаем и выводим штрихкод в область командой:
Код 1C v 8.х ОбластьЗначение.Рисунки.Штрихкод.Картинка = ПолучитьКартинкуШтрихкода(ВнешняяКомпонента, Штрихкод, 50, 30);
Где
Штрихкод – переменная, содержащая строку штрихкода номенклатуры, 50 – требуемая ширина, 30 – высота картинки. В макете размер картинки лучше всего поставить «Реальный размер».
Замечание. Сразу бросается в глаза то, что я вручную указываю размер требуемой картинки – 50 на 30. Возникает вопрос, а нельзя ли размеры требуемой картинки получить из картинки на макете? Конечно можно:
Код 1C v 8.х ОбластьЗначение.Рисунки.Штрихкод.Ширина
ОбластьЗначение.Рисунки.Штрихкод.Высота
К сожалению, цифры получаемые этими командами почему-то слишком малы. Как получить реальный видимый размер картинки я пока не знаю, может кто подскажет?
Источник Пример кода быстрая Печать таблицы значений
Код 1C v 8.х //ТПОтчета - Табличное поле с формы (Таблица значений) с данными
ПострПечать = Новый ПостроительОтчета;
ПострПечать.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТПОтчета);
ПострПечать.МакетОформления = ПолучитьМакетОформления(СтандартноеОформление.Интерфейс);
ПострПечать.Выполнить();
Для каждого Колонка Из ПострПечать.ВыбранныеПоля Цикл
Колонка.Представление = ТПОтчета.Колонки[Колонка.Имя].Заголовок;
КонецЦикла;
ПострПечать.Вывести();
Пример функций Печать таблицы значений с использованием Макета
Код 1C v 8.х //Процедура формирует и выводит отчет по переданной таблице значений
// Параметры :
// ТЗ - ТаблицаЗначений
Процедура УниверсальныйОтчетПоТЗ(ТЗ)
Табл=Новый ТабличныйДокумент;
Макет = ЭтотОбъект.ПолучитьМакет("Макет");
ОбластьШапкаОсновной=Макет.ПолучитьОбласть("Шапка|Основной");
ОбластьСтрокаОсновной=Макет.ПолучитьОбласть("Строка|Основной");
ОбластьИтогОсновной=Макет.ПолучитьОбласть("Итог|Основной");
ОбластьШапкаДОП=Макет.ПолучитьОбласть("Шапка|Показатели");
ОбластьСтрокаДОП=Макет.ПолучитьОбласть("Строка|Показатели");
ОбластьИтогДОП=Макет.ПолучитьОбласть("Итог|Показатели");
Табл.Вывести(ОбластьШапкаОсновной);
Для Каждого Колонка из Тз.Колонки ЦИКЛ
ОбластьШапкаДОП.Параметры.ИмяПоказателя=Колонка.Имя;
Табл.Присоединить(ОбластьШапкаДОП);
КонецЦикла;
счетчик=0;
Для каждого стр из Тз Цикл
счетчик=счетчик+1;
ОбластьСтрокаОсновной.Параметры.счетчик=счетчик;
Табл.Вывести(ОбластьСтрокаОсновной);
Для Каждого Колонка из Тз.Колонки ЦИКЛ
ОбластьСтрокаДОП.Параметры.ЗначениеКолонки=стр[Колонка.Имя];
Табл.Присоединить(ОбластьСтрокаДОП);
КонецЦикла;
КонецЦикла;
Табл.Вывести(ОбластьИтогОсновной);
Для Каждого Колонка из Тз.Колонки ЦИКЛ
ОбластьИтогДОП.Параметры.Итог=Тз.Итог(Колонка.Имя);
Табл.Присоединить(ОбластьИтогДОП);
КонецЦикла;
Табл.Показать();
КонецПроцедуры
Код 1C v 7.x
//Вывести таблицу значений
Процедура ПечатьТЗвТаб(ТЗ, Заголовок = "",КолонкиПоНазваниям = 0) Экспорт
Перем ТТЗ;
ТЗ.Выгрузить(ТТЗ);
МаксШирина = 50; // максимальная ширина колонки
СпШирина = СоздатьОбъект("СписокЗначений"); // список ширин колонок по таблице
Для сч = 1 по ТТЗ.КоличествоКолонок() Цикл
Если КолонкиПоНазваниям = 0 Тогда
ИмяРек = ТТЗ.ПолучитьПараметрыКолонки(сч);
Иначе
ИмяРек = "";
ТТЗ.ПолучитьПараметрыКолонки(сч,,,,ИмяРек,);
КонецЕсли;
СпШирина.ДобавитьЗначение(СтрДлина(ИмяРек)*1.2); // с поправкой на размер шрифта
КонецЦикла;
// просто печать таблицы - вывод всех строк и колонок
// числовые значения - по правому краю. Автоподбор ширины - в пределах МаксШирина
Таб=СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("ПечатьТЗ");
Если СокрЛП(Заголовок) <> "" Тогда
Таб.ВывестиСекцию("Шапка");
КонецЕсли;
// заголовки таблицы
Таб.ВывестиСекцию("Строка|Общая");
Для сч=1 по ТТЗ.КоличествоКолонок() Цикл
Если КолонкиПоНазваниям = 0 Тогда
ИмяРек = ТТЗ.ПолучитьПараметрыКолонки(сч);
Иначе
ИмяРек = "";
Ном = "";
ТТЗ.ПолучитьПараметрыКолонки(сч,,,,ИмяРек,);
КонецЕсли;
Таб.ПрисоединитьСекцию("Строка|Столбец");
КонецЦикла;
ВысотаШапки = Таб.ВысотаТаблицы();
// данные таблицы по строкам
ТТЗ.ВыбратьСтроки();
Пока ТТЗ.ПолучитьСтроку()=1 Цикл
Ном = ТТЗ.НомерСтроки;
Таб.ВывестиСекцию("Строка|Общая");
Выс = Таб.ВысотаТаблицы();
Для сч=1 по ТТЗ.КоличествоКолонок() Цикл
ИмяРек=ТТЗ.ПолучитьЗначение(Ном,сч);
Таб.ПрисоединитьСекцию("Строка|Столбец");
Если ТипЗначения(ИмяРек) = 1 Тогда
Обл = Таб.Область("R"+Выс+"C"+(Сч+1)); // ячейка в которую поместили данные
Обл.ГоризонтальноеПоложение(2); // числа - вправо
КонецЕсли;
НачШирина = СпШирина.ПолучитьЗначение(Сч);
Ширина = СтрДлина(ИмяРек);
СпШирина.УстановитьЗначение(Сч,Макс(НачШирина,Ширина));
КонецЦикла;
КонецЦикла;
Для сч = 1 по СпШирина.РазмерСписка() Цикл
Обл = Таб.Область("R"+ВысотаШапки+"C"+(Сч+1));
// форматируем ширину таблицы
Ширина = Мин(МаксШирина,2+СпШирина.ПолучитьЗначение(Сч));
Обл.ШиринаСтолбца(Ширина);
// форматируем заголовок
Обл.Полужирный(1);
КонецЦикла;
Таб.Показать(Заголовок);
Таб.ТолькоПросмотр(1);
КонецПроцедуры
ИЛИ
Код 1C v 7.x Процедура глВывестиТаблицуЗначений(ТаблицаЗначений, Заголовок = "") Экспорт
Перем Таб, ИИ, ЖЖ, НазваниеКолонки, ТипКолонки, Ширина, Значение, Сообщение;
Таб = СоздатьОбъект("Таблица");
Если ТипЗначенияСтр(ТаблицаЗначений) <> "ТаблицаЗначений" Тогда
Сообщение = "В процедуру ""глВывестиТаблицуЗначений()"" передана переменная не типа ""ТаблицаЗначений"", "+
"а типа """+СокрЛП(ТипЗначенияСтр(ТаблицаЗначений))+"""";
Таб.Область(1, 1, 1, 1).Текст = Сообщение;
Таб.Область(1, 1, 1, 1).ШиринаСтолбца(СтрДлина(Сообщение));
Таб.ТолькоПросмотр(1);
Таб.Показать("Не таблица значений: "+Заголовок);
Возврат;
КонецЕсли;
Для ЖЖ = 1 по ТаблицаЗначений.КоличествоКолонок() цикл
ТаблицаЗначений.ПолучитьПараметрыКолонки(ЖЖ,,,, НазваниеКолонки);
Таб.Область(1, ЖЖ, 1, ЖЖ).Текст = СокрЛП(НазваниеКолонки);
Таб.Область(1, ЖЖ, 1, ЖЖ).РамкаОбвести(5, 5, 5, 5);
Таб.Область(1, ЖЖ, 1, ЖЖ).ВертикальноеПоложение(3);
Таб.Область(1, ЖЖ, 1, ЖЖ).ГоризонтальноеПоложение(3);
Таб.Область(1, ЖЖ, 1, ЖЖ).РазмерШрифта(7);
Таб.Область(1, ЖЖ, 1, ЖЖ).Полужирный(1);
Ширина = Таб.Область(1, ЖЖ, 1, ЖЖ).ШиринаСтолбца();
Ширина = Макс(Ширина, СтрДлина(СокрЛП(НазваниеКолонки)));
Таб.Область(1, ЖЖ, 1, ЖЖ).ШиринаСтолбца(Ширина);
КонецЦикла;
Для ИИ = 1 по ТаблицаЗначений.КоличествоСтрок() цикл
Для ЖЖ = 1 по ТаблицаЗначений.КоличествоКолонок() цикл
Значение = ТаблицаЗначений.ПолучитьЗначение(ИИ, ЖЖ);
Таб.Область(ИИ+1, ЖЖ, ИИ+1, ЖЖ).Текст = Значение;
Таб.Область(ИИ+1, ЖЖ, ИИ+1, ЖЖ).Расшифровка(Значение, 0);
Таб.Область(ИИ+1, ЖЖ, ИИ+1, ЖЖ).РамкаОбвести(3, 0, 3, 0);
Ширина = Таб.Область(1, ЖЖ, 1, ЖЖ).ШиринаСтолбца();
Ширина = Макс(Ширина, СтрДлина(СокрЛП(Строка(Значение))));
Таб.Область(1, ЖЖ, 1, ЖЖ).ШиринаСтолбца(Ширина);
ТаблицаЗначений.ПолучитьПараметрыКолонки(ЖЖ, ТипКолонки); ;
Если ТипКолонки = "Число" тогда
Таб.Область(ИИ+1, ЖЖ, ИИ+1, ЖЖ).ГоризонтальноеПоложение(2);
КонецЕсли;
Если ИИ = ТаблицаЗначений.ТекущаяСтрока() тогда
Таб.Область(ИИ+1, ЖЖ, ИИ+1, ЖЖ).ЦветФона(255, 0, 0);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Таб.ТолькоПросмотр(1);
Таб.Показать("Таблица значений: "+Заголовок);
КонецПроцедуры