Формирование линейных штрих-кодов без использования внешних компонент и шрифтов (3 способа)




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

25 Comments

  1. DitriX

    Вы бы поставили акецент на мобильную платформу в данном вопросе. Так как там нет внешних компонент и шрифты врядли работать будут так как надо.

    Reply
  2. Pasha1st

    (1) DitriX, Согласен. Специально не проверял, но методы должны работать во всех режимах, включая мобильное приложение и веб-клиента.

    Reply
  3. @lexandr

    Для принтера этикеток скорей всего в терминале подставился драйвер remote desktop easy print. В этом случае этикетка будет распечатана правильно, штрих код на ней выйдет, но этот штрих код читаться сканером штрих кодов не будет. Нужно в учетной политике сервера терминалов отключать использование remote desktop easy print и устанавливать родной драйвер принтера этикеток. А так не разу не было ситуации, чтобы из под терминала печатались этикетки, которые потом прочитать нельзя было, всегда такие проблемы решались либо правильной настройкой параметров печати, либо remote desktop easy print, либо настройка этикетки.

    Reply
  4. Pasha1st

    (3) @lexandr, возможно, но прав на администрирование терминальных серверов у меня нет, и подобную настройку вряд ли будут делать — на этих серверах пользователи из разных регионов с разным железом сидят.

    Reply
  5. CheBurator

    Вариант формирования шк на основе мокселя на портале был опубликован давным давно

    Reply
  6. Pasha1st

    (5) CheBurator, и что? С ходу нашел только ean13, мне он не подходит. И способов сделал 3, внедрение в MXL добавлял потому что сделать было просто на базе всего остального.

    Reply
  7. 1cmax

    МОЩНО. формирование двоичных данных в коде!

    Reply
  8. etmarket

    Очень полезная обработка. Сам уже замучался устанавливать шрифты ШК в ОС для разных клиентов, чтобы ценник с ШК печатать.

    Reply
  9. jobkostya1c8

    Тоже запомню на всякий случай. Посмотрю что за работа с двоичным кодом.

    Reply
  10. CheBurator

    (6) претензий вообщем нет

    Заявлены СПОСОБЫ — поэтому я на этом и уперся

    Reply
  11. Prometeus2011

    Однозначно, большой плюс. Практическая применимость неоспорима.

    Reply
  12. eugeniezheludkov

    Прикольно так заморачиваться низкоуровневым кодированием , но судя по коду автор явно пришел в 1с из ANSI С в крайнем случае из CPP 🙂 переменные в одну букву :). Мелочи: «остаток=ч1-рез*ч2;» можно заменить на «Остаток = ч1%ч2» но в других местах автор почему-то использует % как остаток от деления. И еще жаль что долго формируется картинка, когда нужно обновить все ценники витрины в магазине то это становится долго, хотя можно и подождать…

    Reply
  13. Pasha1st

    (12) eugeniezheludkov, то что 1С для меня не основной и не первый язык и среда — угадал. Но в конкретном данном случае — деление уже произведено, умножение обычно работает быстрее. Мелочь, а приятно. В режиме растровой картинки (BMP/PNG) формирование долгое, да, WMF и вставка в табличный документ штрихов работают существенно быстрее.

    Провел бенчмарк:

    12.01.2015 12:17:53 начало тестирования — BMP, без подписи

    Затрачено 20с, сформировано 41 кадров, 2,05к/с

    12.01.2015 12:18:13 начало тестирования — BMP, c подписью

    Затрачено 20с, сформировано 14 кадров, 0,7к/с

    12.01.2015 12:18:33 начало тестирования — WMF

    Затрачено 20с, сформировано 1 024 кадров, 51,2к/с

    12.01.2015 12:18:53 начало тестирования — табличный

    Затрачено 20с, сформировано 2 880 кадров, 144к/с

    Reply
  14. Rustig

    (3) @lexandr, типичный случай проблем с печатью через удаленный сеанс. много копьев уже сломано: http://forum.infostart.ru/forum72/topic105761/

    Reply
  15. Pasha1st

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

    Reply
  16. FSerg

    Очень выручила обработка, потому что у 1С-компоненты печати штрих-кода кривая поддержка формата Interleaved 2 of 5. Вроде бы стандарт поддерживается, но работает только с контрольной цифрой, а иногда она не используется.

    Если вы добавите себе в обработку вот эту функцию, то будет еще и поддержка Interleaved 2 of 5 (правда без контрольной цифры)

    Функция штрих_Interleaved2of5(стр) Экспорт
    
    СтартСимволы=»1111″;
    
    рез=»»;
    Для Н=1 по СтрДлина(стр) Цикл
    с=ВРег(Сред(стр,Н,1));
    если с=»0″ тогда
    рез=рез+»11331″;
    ИначеЕсли с=»1″ тогда
    рез=рез+»31113″;
    ИначеЕсли с=»2″ тогда
    рез=рез+»13113″;
    ИначеЕсли с=»3″ тогда
    рез=рез+»33111″;
    ИначеЕсли с=»4″ тогда
    рез=рез+»11313″;
    ИначеЕсли с=»5″ тогда
    рез=рез+»31311″;
    ИначеЕсли с=»6″ тогда
    рез=рез+»13311″;
    ИначеЕсли с=»7″ тогда
    рез=рез+»11133″;
    ИначеЕсли с=»8″ тогда
    рез=рез+»31131″;
    ИначеЕсли с=»9″ тогда
    рез=рез+»13131″;
    Иначе
    возврат «»;
    КонецЕсли;
    КонецЦикла;
    
    // а теперь перетасуем группы по 5 символов между собой, чтобы получить итоговый код для генерации
    // так как мы будем обрабатывать сразу по две пары групп, то делим на два
    РезНовый=»»;
    Поз=0;
    КолПарГрупп = СтрДлина(стр)/2;
    Для НомерПары=1 по КолПарГрупп Цикл
    // Перебираем посимвольно каждую группу
    Для й=1 по 5 Цикл
    Символ1 = Сред(рез,Поз+й,1);
    Символ2 = Сред(рез,Поз+й+5,1);
    РезНовый = РезНовый+Символ1+Символ2;
    КонецЦикла;
    Поз = Поз + 10;
    КонецЦикла;
    
    СтопСимволы = «311»;
    
    Возврат СтартСимволы + РезНовый + СтопСимволы;
    
    КонецФункции
    

    Показать

    Reply
  17. DanilaDru

    Добрый день.

    Подскажите пожалуйста по поводу макета font. Дело в том что в обработке, которая предоставлена в публикации есть только font16, других размеров нет.

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

    Не могли бы вы выложить макеты с другими размерами?

    Спасибо.

    Reply
  18. lsnr

    А можно ли доработать эту обработку чтобы она формировала штрих-код в формате EAN128 ?

    Reply
  19. Pasha1st

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

    Reply
  20. mvsemenov

    Автору БОЛЬШОЙ респект, в формате WMF EAN-13 читается вплоть до 15мм (ширина)

    Reply
  21. info1i

    Превосходно! Супер-мега-крутая вещь! Много положительных эмоций! Благодарю! То, над чем я ломал голову, уже, оказывается есть, еще и с вариантами и настройками. Я тоже столкнулся с проблемой на терминальных серверах, но в основном цель была — чтобы конфигурация не зависела от каких-то драйверов, компонент и прочей ерунды, чисто код 1С, и эта статья и обработка помогла мне решить задачу. В интернете аналогов не нашел, так что, похоже, Вы первый по данной теме, по крайней мере в 1С.

    Reply
  22. Lapitskiy

    отличная вещь!

    Reply
  23. PavelKolobkov

    (16)

    Если вы добавите себе в обработку вот эту функцию, то будет еще и поддержка Interleaved 2 of 5 (правда без контрольной цифры)

    Что вы имеете ввиду? Без контрольной цифры.

    Есть задача печатать почтовые бланки Почты РФ, у них специальные требования к штрихкоду. Обязательно должен быть тип Interleaved 2 of 5.

    Reply
  24. FSerg

    (23) Я уже не вспомню в чем была проблема, но то что формировала библиотека от 1С не подходило. 🙁

    Помогло данное решение 🙂

    Reply
  25. crimeait

    Пытался вот такой ШК «0016754000001188592040418000003106» (CODE128) получить в формате WMF . Сканером так и не получилось его считать. Полоски сливаются. Хотя EAN13 формирует и читает нормально.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *