Книга знаний

1С:Предприятие

Преобразование строки в штрихкод 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); //Аски код

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика