Имя: Пароль:
1C
1С v8
Шрифт EAN gnivc, алгоритм печати дополнений (EAN 13+5) или code39
0 AlteZ
 
20.03.12
05:04
1CBarCod.dll сожрал всю память
сделал печать 13-значных шк через eangnivc.ttf,
а как быть с кодами печатных изданий длины 13+2, 13+4, 13+5 ?

// Дополнения для ШК
Функция ТолькоЦифры(Штрихкод)
   Для Сч = 1 По СтрДлина(Штрихкод) Цикл
       Символ = Сред(Штрихкод, Сч, 1);
       Если НЕ(Найти("0123456789", Символ)) Тогда
           Возврат Ложь;
       КонецЕсли;
   КонецЦикла;
   Возврат Истина;
КонецФункции

Функция КонтрольныйСимвол_EAN(ШтрихКод,Тип) Экспорт
   Четн   = 0;
   Нечетн = 0;
   КоличествоИтераций = ?(Тип = 13, 6, 4);
   Для Индекс = 1 По КоличествоИтераций Цикл
       Если (Тип = 8) и (Индекс = КоличествоИтераций) Тогда
       Иначе
           Четн   = Четн   + Сред(ШтрихКод, 2 * Индекс, 1);
       КонецЕсли;
       Нечетн = Нечетн + Сред(ШтрихКод, 2 * Индекс - 1, 1);
   КонецЦикла;
   Если Тип = 13 Тогда
       Четн = Четн * 3;
   Иначе
       Нечетн = Нечетн * 3;
   КонецЕсли;
   КонтЦифра = 10 - (Четн + Нечетн) % 10;
   Возврат ?(КонтЦифра = 10, "0", Строка(КонтЦифра));
КонецФункции

Функция Проверить_ШтрихКод(ШтрихКод)
   ДлинаКода = СтрДлина(Штрихкод);
   Если ДлинаКода = 0 Тогда
       Возврат Ложь;
   ИначеЕсли ТолькоЦифры(Штрихкод) Тогда // штрих-код должен состоять из цифр
       Если ДлинаКода = 13 Тогда
           Если КонтрольныйСимвол_EAN(Лев(Штрихкод,12), 13) <> Прав(Штрихкод, 1) Тогда
               Возврат Ложь;
           КонецЕсли;
       ИначеЕсли ДлинаКода = 8 Тогда
           Если КонтрольныйСимвол_EAN(Лев(Штрихкод, 7), 8 ) <> Прав(Штрихкод, 1) Тогда
               Возврат Ложь;
           КонецЕсли;
       Иначе
           Возврат Ложь;
       КонецЕсли;
   Иначе
       Возврат Ложь;
   КонецЕсли;
   Возврат Истина;
КонецФункции

Функция ПолучитьКомбинацию(ИсхЧисло,Тип="X",НижнееРасположение=Истина)
   // Символы из таблицы для нижнего расположения
   //   по типам
   Если НижнееРасположение Тогда
       Если Тип = "A"    Тогда
           Возврат(Строка(ИсхЧисло));
       ИначеЕсли Тип = "B" Тогда
           Возврат(Символ(ИсхЧисло + 65));
       ИначеЕсли Тип = "C" Тогда
           Возврат(Символ(ИсхЧисло + 97));
       // Для первого знака без символов ШК только для нижнего положения
       Иначе
           Возврат(Символ(ИсхЧисло + 35));
       КонецЕсли;
   Иначе
       Если Тип = "A"    Тогда
           Возврат(Символ(ИсхЧисло + 107));
       ИначеЕсли Тип = "B" Тогда
           Возврат(Символ(ИсхЧисло + 75));
       ИначеЕсли Тип = "C" Тогда
           Если ИсхЧисло < 5 Тогда
               Возврат(Символ(ИсхЧисло + 86));
           Иначе
               Возврат(Символ(ИсхЧисло + 118 - 5));
           КонецЕсли;
       // Для первого знака без символов ШК пусто :-) лень рисовать шрифт
       Иначе
           Возврат(Символ(32));
       КонецЕсли;
   КонецЕсли;
КонецФункции

Функция ПроверитьКод(ШтрихКод, Тип)
   Четн   = 0;
   Нечетн = 0;
   КоличествоИтераций = ?(Тип = 13, 6, 4);
   Для Индекс = 1 По КоличествоИтераций Цикл
       Если (Тип = 8) и (Индекс = КоличествоИтераций) Тогда
       Иначе
           Четн   = Четн   + Сред(ШтрихКод, 2 * Индекс, 1);
       КонецЕсли;
       Нечетн = Нечетн + Сред(ШтрихКод, 2 * Индекс - 1, 1);
   КонецЦикла;
   Если Тип = 13 Тогда
       Четн = Четн * 3;
   Иначе
       Нечетн = Нечетн * 3;
   КонецЕсли;
   КонтЦифра = 10 - (Четн + Нечетн) % 10;
   Если  КонтЦифра = 10 Тогда КонтЦифра  = 0; КонецЕсли;
   Возврат ?(Число(Прав(ШтрихКод,1)) = КонтЦифра, 11, КонтЦифра);
КонецФункции

Функция ПреобразованиеШК(ШК,ЦифрыВнизу=Истина)
   СтрокаШК ="";
   // Только для EAN8
   Если СтрДлина(ШК) = 8 Тогда
           СтрокаШК =
               "!" +
               ПолучитьКомбинацию(Число(Сред(ШК,1,1)),"A",ЦифрыВнизу) +
               ПолучитьКомбинацию(Число(Сред(ШК,2,1)),"A",ЦифрыВнизу) +
               ПолучитьКомбинацию(Число(Сред(ШК,3,1)),"A",ЦифрыВнизу) +
               ПолучитьКомбинацию(Число(Сред(ШК,4,1)),"A",ЦифрыВнизу) +
               "-" +
               ПолучитьКомбинацию(Число(Сред(ШК,5,1)),"C",ЦифрыВнизу) +
               ПолучитьКомбинацию(Число(Сред(ШК,6,1)),"C",ЦифрыВнизу) +
               ПолучитьКомбинацию(Число(Сред(ШК,7,1)),"C",ЦифрыВнизу) +
               ПолучитьКомбинацию(Число(Сред(ШК,8,1)),"C",ЦифрыВнизу) +
               "!";
       Возврат(СтрокаШК);            
   // Только EAN13
   ИначеЕсли СтрДлина(ШК) = 13 Тогда
       // Для печати цифр внизу ШК
       Если ЦифрыВнизу Тогда
           СтрокаШК =
               ПолучитьКомбинацию(Число(Сред(ШК,1,1)));                 //13
       КонецЕсли;
           СтрокаШК = СтрокаШК +  "!";
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,2,1)),"A",ЦифрыВнизу);  //12
               
           Если Число(Сред(ШК,1,1)) < 4 Тогда                           //11
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,3,1)),"A",ЦифрыВнизу);
           Иначе
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,3,1)),"B",ЦифрыВнизу);
           КонецЕсли;
                                                                        //10
           Если ((Число(Сред(ШК,1,1)) = 0) ИЛИ
                  (Число(Сред(ШК,1,1)) = 4) ИЛИ
                   (Число(Сред(ШК,1,1)) = 7) ИЛИ
                    (Число(Сред(ШК,1,1)) = 8)) Тогда
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,4,1)),"A",ЦифрыВнизу);
           Иначе
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,4,1)),"B",ЦифрыВнизу);
           КонецЕсли;
                                                                        //09
           Если ((Число(Сред(ШК,1,1)) = 0) ИЛИ
                  (Число(Сред(ШК,1,1)) = 1) ИЛИ
                   (Число(Сред(ШК,1,1)) = 4) ИЛИ
                    (Число(Сред(ШК,1,1))  =5) ИЛИ
                     (Число(Сред(ШК,1,1))  =9)) Тогда
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,5,1)),"A",ЦифрыВнизу);
           Иначе
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,5,1)),"B",ЦифрыВнизу);
           КонецЕсли;
                                                                        //08
           Если ((Число(Сред(ШК,1,1)) = 0) ИЛИ
                  (Число(Сред(ШК,1,1)) = 2) ИЛИ
                   (Число(Сред(ШК,1,1)) = 5) ИЛИ
                    (Число(Сред(ШК,1,1)) = 6) ИЛИ
                     (Число(Сред(ШК,1,1)) = 7 )) Тогда
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,6,1)),"A",ЦифрыВнизу);
           Иначе
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,6,1)),"B",ЦифрыВнизу);
           КонецЕсли;
                                                                        //07
           Если ((Число(Сред(ШК,1,1)) = 0) ИЛИ
                  (Число(Сред(ШК,1,1)) = 3) ИЛИ
                   (Число(Сред(ШК,1,1)) = 6) ИЛИ
                    (Число(Сред(ШК,1,1)) = 8) ИЛИ
                     (Число(Сред(ШК,1,1)) = 9)) Тогда
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,7,1)),"A",ЦифрыВнизу);
           Иначе
           СтрокаШК = СтрокаШК    +
               ПолучитьКомбинацию(Число(Сред(ШК,7,1)),"B",ЦифрыВнизу);
           КонецЕсли;
           
           СтрокаШК = СтрокаШК    +
               "-" +
               ПолучитьКомбинацию(Число(Сред(ШК,8,1)),"C",ЦифрыВнизу)  +  // 08
               ПолучитьКомбинацию(Число(Сред(ШК,9,1)),"C",ЦифрыВнизу)  +  // 09
               ПолучитьКомбинацию(Число(Сред(ШК,10,1)),"C",ЦифрыВнизу) +  // 10
               ПолучитьКомбинацию(Число(Сред(ШК,11,1)),"C",ЦифрыВнизу) +  // 11
               ПолучитьКомбинацию(Число(Сред(ШК,12,1)),"C",ЦифрыВнизу) +  // 12
               ПолучитьКомбинацию(Число(Сред(ШК,13,1)),"C",ЦифрыВнизу) +  // 13
               "!";
       Возврат(СтрокаШК);            
   КонецЕсли;
КонецФункции
// Конец дополнений для ШК

Функция ПолучитьЗначениеТипаШтрихкодаДляЭУ(ТипКода)
   Перем Значение;
   
   Если ТипКода = ПланыВидовХарактеристик.ТипыШтрихкодов.EAN8 Тогда
       Значение = 0;
   ИначеЕсли ТипКода = ПланыВидовХарактеристик.ТипыШтрихкодов.EAN13 Тогда
       Значение = 1;
   ИначеЕсли ТипКода = ПланыВидовХарактеристик.ТипыШтрихкодов.EAN128 Тогда
       Значение = 2;
   ИначеЕсли ТипКода = ПланыВидовХарактеристик.ТипыШтрихкодов.Code39 Тогда
       Значение = 3;
   ИначеЕсли ТипКода = ПланыВидовХарактеристик.ТипыШтрихкодов.Code128 Тогда
       Значение = 4;
   Иначе
       Значение = -1;
   КонецЕсли;
   
   Возврат Значение;
КонецФункции // ПолучитьЗначениеТипаШтрихкодаДляЭУ()




Процедура КнопкаВыполнитьНажатие(Кнопка)  
   ШтрихКод="4607098750105";//+12004
           Если Проверить_ШтрихКод(ШтрихКод)=Ложь Тогда
               //сообщить("Товар: "+Товар+" - Не имеет штрих кода");
               ИтШК="";
           Иначе
               Проверка = Ложь;
               Если СтрДлина(ШтрихКод)=8 Тогда
                   Проверка = Число(ПроверитьКод(ШтрихКод,8));
               ИначеЕсли СтрДлина(ШтрихКод)=13 Тогда
                   Проверка = Число(ПроверитьКод(ШтрихКод,13));
               ИначеЕсли (СтрДлина(ШтрихКод) <> 8) и (СтрДлина(ШтрихКод) <> 13) Тогда
                   Сообщить("Ошибка: код не содержит нужное кол-во символов символов");
                   //Продолжить;
               КонецЕсли;
               // Все введено правильно преобразуем
               Если Проверка = 11 Тогда
                   ИтШК = ПреобразованиеШК(ШтрихКод,Истина);
               КонецЕсли;
           КонецЕсли;
           ЭлементыФормы.птд.рисунки.шк.Текст=ИтШК;

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



Пока    ШтрихКод="4607098750105" все ок, а есть ещё и "460709875010512004"
1 AlteZ
 
20.03.12
05:47
Книга знаний: Преобразование строки в штрихкод Code128 с адаптивным способом смены подсистемы кодирования. перевел на v8, всё ёще не генерит читаемый сканером длинный ШК

Перем АскиБар;      //Массив для преобразования АскиКод - БарКод
Перем ВыхТ;

//Если параметр цифра возвращает 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;
   Для каждого строкаВТ Из ВыхТ Цикл
       Если Ном > 0 тогда
           Сум = Мод(Сум+строкаВТ.А*Ном,103);
           Вых = Вых+Сред(АскиБар,(строкаВТ.А+1)*3-2,3);
       Иначе    
           Сум = Мод(строкаВТ.А,103);
       КонецЕсли;
       Ном = Ном+1;
   КонецЦикла;
   Возврат(Вых+Сред(АскиБар,(Сум+1)*3-2,3)+"@");
КонецФункции

Процедура ПриОткрытии()
     ШтрихКод="4607098750105";//12004
   ЭлементыФормы.птд.рисунки.шк.Текст=БарКод(СокрЛП(ШтрихКод),6);
   
 //Форма.Параметр = БарКод(СокрЛП(Форма.Параметр),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); //Аски код //,,,,"Аск",4

2 AlteZ
 
20.03.12
06:07
само собой, книги рулят,
но раз 21 век, может, есть уже готовый велосипед (без OCX)?
3 Mikeware
 
20.03.12
06:26
Гнивцем код39 не напечатаешь. Боюсь, что аддоны тоже. Но тем не менее, в сети есть фонты для печати и еанов, и код39-код128 и иже...
алгоритм лежит в англицкой пидовикии..
4 AlteZ
 
24.03.12
16:22
В итоге (1) работает, щрифт брать тут: http://code128.narod.ru/