Преобразование строки в штрихкод Code128 с адаптивным способом смены подсистемы кодирования.Обработка, на вход даем строку, на выходе получаем строку, которую вставляем куда нужно (форма, отчет), назначая шрифт Barcode.ttf. Отличия - адаптивный способ смены подсистемы кодирования. | | Автор статьи: TEN | Редакторы: Последняя редакция №4 от 07.11.06 | История URL: http://kb.mista.ru/article.php?id=404 | |
Ключевые слова: штрихкод, Code128
Обсуждение: code128 как сформировать
Критерии смены подсистемы кодирования.
Стандарт штрихкода Code 128 предусматривает три подсистемы кодирования.
А (моде=1) - управляющие знаки, входной аски < 32,
В (моде=2) - символы, текст вперемежку с цифрами, (65 - английская A)
С (моде=3) - группа цифр. Каждая пара кодируется как символ с номером равным паре цифр (65 - два знака, цифры 6 и 5.
Идея в следующем: анализируем Н следующих знаков. Если все знаки - цифры, переходим в Моде3
По умолчанию Н=2 (во всех встреченных кодерах), мы принимаем Н=6. Основание - компактность.
Обозначения.
Для входного текста
Б - Буква,
Ц - Цифра,
Для выходного текста
А - знак в подсистеме А
В - знак в подсистеме В
С - знак в подсистеме С
П - знак команды смены подсистемы
Для Н=2 (начальную команду перехода опускаем)
Вход БЦЦБ (4 знака)
С переходом Выход = ВПСПВ (5 знаков)
Без перехода Выход ВВВВ (4 знака)
Т.е. экономим на ЦЦ-С но добавляются ПП. Выход длинее входа
Для Н > 4
Вход БЦЦЦЦБ (6 знаков)
С переходом Выход = ВПССПВ (6 знаков)
Без перехода Выход ВВВВВВ (6 знака)
Выход равен входу
Для Н > 6
Вход БЦЦЦЦЦЦБ (8 знаков)
С переходом Выход = ВПСССПВ (7 знаков)
Без перехода Выход ВВВВВВВВ (8 знака)
Выход короче входа.
Т.о получаем набор триггеров переходов:
Для перехода в С - Не С и группа из 6 и более цифр.
Для перехода в В - Не В и любой знак кроме цифры или команды
Для перехода в А - Не А и любая команда (аски <32)
Собственно исходник
Перем АскиБар; //Массив для преобразования АскиКод - БарКод
Перем ВыхТ;
//Если параметр цифра возвращает 1
Функция ТипСимв(КодСмв)
Если КодСмв < 32 Тогда
Возврат(1); //Команда
ИначеЕсли (48 <= КодСмв) и (КодСмв<=57) Тогда
Возврат(3); //Цифра
Иначе
Возврат(2); //Буква, знак
КонецЕсли;
КонецФункции
Функция Мод(Ч,З)
Возврат(Ч-Цел(Ч/З)*З);
КонецФункции
Функция БарКод(Вход,БазаМодеС=6)
//Фильтр пустого входа
Если Вход = "" Тогда Возврат(""); КонецЕсли;
//Очищаем выход
ВыхТ.УдалитьСтроки();
Дл = СтрДлина(СокрЛП(Вход));
//Разборки со стартовым кодом
//Принимаем решение о смене подсистемы кодирования "моде" (А-1, В-2, С-3)
//Анализируем тип двух первых символов
ТекСимв = КодСимв(Сред(Вход,1,1));
ТипТекСимв = ТипСимв(ТекСимв);
Если Дл > 1 тогда
СлСимв = КодСимв(Сред(Вход,2,1));
ТипСлСимв = ТипСимв(СлСимв);
Иначе
ТипСлСимв = 2;
КонецЕсли;
Моде = ТипТекСимв;
Если (ТипТекСимв = 3) и (ТипСлСимв = 3) тогда Моде = 3; КонецЕсли;
//В выходную таблицу добавляем символ старта подсистемы
ВыхТ.НоваяСтрока();
ВыхТ.А = 102 + Моде;
Вых = Симв(64 + Моде);
//Анализируем входные символы
Для Сч = 1 по Дл Цикл
ТекСимв = КодСимв(Сред(Вход,Сч,1));
Если ТекСимв > 127 тогда
Сообщить("Символ № "+Сч+ " со значением="+ ТекСимв+" не разрешен в штрихкоде");
Продолжить;
КонецЕсли;
ТипТекСимв = ТипСимв(ТекСимв);
//Принимаем решение о смене подсистемы кодирования (моде).
Если ТипТекСимв <> Моде тогда
Если ТипТекСимв < 3 Тогда
//Нужно менять моде либо с А на В, либо с В на А
ВыхТ.НоваяСтрока();
Если Моде = 1 тогда
ВыхТ.А = 100; //Переключаемся из А в В
Иначе
ВыхТ.А = 101; //Переключаемся из В в А
КонецЕсли;
Моде = ТипТекСимв;
Иначе
//Находимся в моде А или В, встретили цифру.
//Прикидываем, стоит ли переключаться в МодеС
//Смотрим на БазаМодеС знаков вперед.
//Оптимально, БазаМодеС = 6 (См. описание)
ДлМ = ?(Дл < Сч+БазаМодеС-1, Дл, Сч+БазаМодеС-1);
СчЦ = 0;
Для СчМ = Сч по ДлМ Цикл
МодМ = ТипСимв(КодСимв(Сред(Вход,СчМ,1)));
//Если цифра - смотрим дальше
Если МодМ = 3 тогда
СчЦ = СчЦ+1;
Продолжить;
Иначе
СчЦ = 0;
Прервать;
КонецЕсли;
КонецЦикла;
//Если нужно переключится в С
Если СчЦ - БазаМодеС = 0 тогда
Моде = 3;
ВыхТ.НоваяСтрока();
ВыхТ.А = 99; //Переключаемся из А или В в С
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Добавляем очередной символ
//Если символ в МодеС
Если Моде = 3 тогда
СлСимв = КодСимв(Сред(Вход,Сч+1,1));
ТипСлСимв = ТипСимв(СлСимв);
//Если входная строка кончается на первой цифре, или
//конец входной строки цифра+не цифра
Если (Сч = Дл) или (ТипТекСимв <> 3) или (ТипСлСимв <> 3) тогда
//Переключаемся из режима С в режим В
Моде = 2;
ВыхТ.НоваяСтрока();
ВыхТ.А = 100;
Иначе
//Добавляем символ в МодеС
Если (ТипТекСимв <> 3) или (ТипСлСимв <> 3) тогда
Сообщить("Ош."+ Сч+" "+ ТекСимв+" "+СлСимв);
Иначе
ВыхТ.НоваяСтрока();
ВыхТ.А = Число(Симв(ТекСимв)+Симв(СлСимв));
Сч = Сч+1;
Продолжить;
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Добавляем символ в МодеА, или МодеВ
ВыхТ.НоваяСтрока();
Если Моде = 1 тогда
ВыхТ.А = ТекСимв+64;
Иначе
ВыхТ.А = ТекСимв-32;
КонецЕсли;
КонецЦикла;
//Считаем контрольную сумму и формируем баркод
ВыхТ.ВыбратьСтроки();
Сум = 0;
Ном = 0;
Пока ВыхТ.ПолучитьСтроку() = 1 Цикл
Если Ном > 0 тогда
Сум = Мод(Сум+ВыхТ.А*Ном,103);
Вых = Вых+Сред(АскиБар,(ВыхТ.А+1)*3-2,3);
Иначе
Сум = Мод(ВыхТ.А,103);
КонецЕсли;
Ном = Ном+1;
КонецЦикла;
Возврат(Вых+Сред(АскиБар,(Сум+1)*3-2,3)+"@");
КонецФункции
Процедура ПриОткрытии()
Форма.Параметр = БарКод(СокрЛП(Форма.Параметр),6);
Форма.Закрыть();
КонецПроцедуры
АскиБар =
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
"155515551449485845458494854548584944056416452065425461560506542164524212245605641254614650"+ //29
"11919191108980988109881889018890898001:0928120290:18212211829021281:0122209281:01218290:10"+ //59
"2305<0;0004=0<540=4<1<05<4105<0=441<4=0<14<50=4050<320=04830047407443074434470344704740113"+ //89
"13131100;0838030380;0308380023032203302";//102
ВыхТ = СоздатьОбъект("ТаблицаЗначений");
ВыхТ.НоваяКолонка("А",,,,"Аск",4); //Аски код
|