Пример генерации штрих-кода для документов, справочников и его расшифровка




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2025-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='\

48 Comments

  1. sva0

    А где обработка?

    Reply
  2. aipnnov

    Добавил. почему-то в первый раз не сохранился.

    Reply
  3. Новый чайник

    Очень подробно и понятно описан третий абзац. Спасибо

    Reply
  4. Angeros

    Автору за усердия однозначный плюс. Вот только вопрос — а можно с помощью этой компоненты прочитать ШК с изображения сканированного.

    Reply
  5. aipnnov

    (4) Компонента, как уже сказано в описании выше, стандартная и формирует только штрихкод, а для того, чтобы прочитать его с помощью сканера с графического изображения необходимо установить драйвер чтения ШК АТОЛ или любой другой.

    Reply
  6. aipnnov

    (4) Это 1С-вская компонента, поэтому она корректно формирует только EAN13, EAN8, Code128 и Code39, а вот EAN128 она как бы формирует, но при чтении сканером код считывается с ошибками т.е. без «(» и «)», в отличие от других, например barcode.ocx

    Reply
  7. ODergunov

    Илья, добрый день. Скажите есть ли icq или skype? Хотелось бы кое-что у Вас уточнить. Можете скинуть на ODergunov@dscompany.kz

    Reply
  8. ODergunov

    «Для проверки с помощью сканера необходимо внести изменения в стандартную обработку конфигурации СерверТО, а именно в модуле обработки в функцию ОбработатьСобытиеСШК добавить код расшифровки(только расшифровки) из модуля формы внешней обработки.»

    Извеняюсь конечно. но что-то не могу найти где этот кусок кода?

    Обработка полезная, давно мучался этим вопросом, но вот нигде найти не мог. Плюс.

    Reply
  9. aipnnov

    (8) Этот кусок кода находится в модуле формы. Необходимо добавить часть кода с начала процедуры до запроса.

    Reply
  10. aipnnov

    (7)(8) Послал смотри мыло.

    Reply
  11. Воронкин

    aipnnov 16.12.2009 19:43:16

    (8) Этот кусок кода находится в модуле формы. Необходимо добавить часть кода с начала процедуры до запроса.

    Вам дважды пишут, что бы Вы более подробно описали свой «третий» абзац. А Вы

    очередной раз отвечеате ахинеей. Если выложил обработку — выложи код, отметь

    куда и что вставить. Не умничай сильно…

    Reply
  12. aipnnov

    (11)Пример обработки написан для тех кто хоть что-то понимает в программировании 1С. Если кто этого не знает, то пишет либо в личку, либо в коментариях. (8) Так и сделал и я ему послал письмо, что и как надо сделать.

    Прежде чем в чем-то обвинять надо смотреть внимательно мои ответы (10).

    Вы я как понял здесь недавно и еще ничего не опубликовали, поэтому …

    Reply
  13. aipnnov

    (11) Остальным все ясно и понятно, судя по коментариям.

    Reply
  14. Арчибальд

    А выведу ка я это в топ 😎

    Reply
  15. Воронкин

    Как раз судя по комментариям нельзя сказать, как Вы утверждаете что

    всем все понятно.

    И не согласен с Вами — Если выкладывается обработка, то для ее запуска

    необходимо писать Вам на почтовый ящик, что бы узнать как она работает.

    Написали бы только заголовок — Штрихкодирование документов, если кому-то

    что-то не понятно — пишите в личку.

    Порадовало, что не поленились посмотреть, когда я зарегистрировался,

    а мне все равно сколько времени Вы на сайте и какой у Вас рейтинг.

    Лично мне разъяснения писать не надо, тема штрихкодирования документов

    довольно популярна, и здесь на сайте обработки выкладываются довольно

    часто, я решал эту тему без снятия с поддержки года два назад.

    Reply
  16. aipnnov
    Если выкладывается обработка, то для ее запуска

    необходимо писать Вам на почтовый ящик, что бы узнать как она работает.

    А вы её скачали, смотрели чтобы утверждать, что она не запускается? Что-то я вас среди 150 скачавших не увидел.

    Как видите скачало на сей момет 150 человек и никто не пожаловался, что она не работает.

    Как раз судя по комментариям нельзя сказать, как Вы утверждаете что всем все понятно.

    Укажите, какие коментарии я оставил без внимания и кому ответил не внятно?

    Писать весь код в коментариях нет необходимости т.к. он не маленький, поэтому кому надо узнать что-либо конкретнее, обращаются как например (7) и (8) коментариях.

    Лично мне разъяснения писать не надо, тема штрихкодирования документов

    довольно популярна, и здесь на сайте обработки выкладываются довольно

    часто, я решал эту тему без снятия с поддержки года два назад.

    Так выложи здесь, пусть люди посмотрят и оценят все-таки здесь есть программисты поопытней меня, а может кому твой опыт и пригодится.

    Reply
  17. Dimasik2007

    (0) Большое спасибо, применил в своем блоке — понравилась автогенерация штрихкода, единственное, как я понял — идет привязка (кроме типа документа, номера) к дате документа, т.е. если исправили в базе документ, то поиск по ш/к не будет успешным. Решил регистром сведений.

    Reply
  18. aipnnov

    (17) Очень рад, что мой труд вам пригодился.

    Шифровать можно любые даные, которые считаете нужными. Исправлять дату документа, например РеализацияТоваровУслуг, а именно дату после того как документ проведен и по нему распечатана накладная или др., настоящий бухгалтер не позволит, ну а если уж пришлось тогда и распечатывается новый документ(накладная) и в нем уже будет другой ШК, в котором будут зашифрованы и номер, и дата. Необходимо для этого генерацию поместить в печать документа и не надо создавать лишний регистр и засорять базу, да и размер ее увеличится, что при файловой не желательно.

    Reply
  19. tlk

    (0) Не смог понять алгоритм кодирования в формате code128, зачем переводить в цифры, если формат штрихкода позволяет работать с ASCII и в результате все равно получаем очень большое число?

    Reply
  20. aipnnov

    (19) Для получения контрольной суммы все равно придется переводить символы в числа.

    Стандарт штрихкода Code 128 предусматривает три подсистемы кодирования:

    А (моде=1) — управляющие знаки, входной аски < 32;

    В (моде=2) — символы, текст вперемежку с цифрами, (65 — английская A)

    С (моде=3) — группа цифр. Каждая пара кодируется как символ с номером равным паре цифр (65 — два знака, цифры 6 и 5.)

    Reply
  21. a_titeev

    дык неправильно работает с кодировкой code128… попробуй например закодировать и раскодировать документ с номером «10001111000»… я так понимаю косяк в раскодировании… скорее всего… короче сочетания цифер 10 смертельны… вместо этого получаем «1000111*!»… нехорошо…

    Reply
  22. Dimasik2007

    (21) Присоединяюсь.

    Reply
  23. Dimasik2007

    (21) Присоединяюсь.

    Пример: код

    1044062991003210024621715211817162323 документ Реализация товаров и услуг 1/52107 от 28.03.2010 9:58:23 — работает хорошо

    104406299100321002462171521181716225 — Реализация товаров и услуг 1/52106 от 28.03.2010 9:57:48 — уже не открывает, видно что 1 символ потерян, причем если дописать справа 1 любой символ (1, 2, 3 etc), то документ найдется.

    Reply
  24. aipnnov

    (23)(21) Исправил, теперь будет декодировать штрихкод 128 без проблем.

    Reply
  25. a_titeev

    (24) Исправил генерацию кода или только раскодирование? А то раскодирование я и у себя уже поправил, но впечатление такое что принцип кодирования был неверен, т.к. приводил к неоднозначности при раскодировании… Но тогда я решил кодирование не трогать принципиально, т.к. сразу не проверил, а потом было поздно — уже напечатали тыЩи документов… 🙂

    Reply
  26. a_titeev

    (24) Исправил кодирование или раскодирование? А то раскодирование уже и у себя поправил кое-как, и сложилось такое впечатление что принцип кодирования неверен, т.к. приводит к неоднозначностям кода при раскодировании. Сам же исправлять кодирование не хотел по той причине что напечатали тыЩи доков уже и сканить именно их надо было…

    Reply
  27. aipnnov

    (26) Исправил раскодирование, теперь проблем не должно быть. А вообще-то этот код, писался не под компоненту 1С, поэтому можно переписать его под нее т.е. из этого кода убрать подсчет контрольной суммы для code 128 при его формировании, а если нет смысла шифрования данных, то убрать и шифрование и оставить как есть тип документа (только в анг.раскладке), номер документа и дату, тогда при включении отображения текста кода будут не цифры а именно текст, который шифруется, но в этом случае может быть большая ширина самого штрихкода. Ну и при раскодировании тоже все изменить.

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

    Reply
  28. Dimasik2007

    (27) На новой версии ошибка.

    Кодируемая строка Реализация товаров и услуг 1/55580 от 23.04.2010 11:43:55

    штрих-код 1044062991004210019621715212121241699 (code128)

    Раскодирование

    {Форма.Форма.Форма(552)}: Преобразование значения к типу Число не может быть выполнено

    Сум = Мод(Сум+Число(СимвКод)*Ном,103);

    Подскажите, где исправить….

    Reply
  29. aipnnov

    (28) Перезалил, видимо что-то не закачалось в первый раз. Теперь пробуй, должно быть все нормально.

    Reply
  30. StAsya_1C

    Если ввожу «неправильный» код для раскодирования, то функция КонтролСумма(СтрокаКода) зацикливается. Копаться в алгоритме совсем не хочется, может поставить остановку по числу итераций? Тогда какое значение должна вернуть эта функция?

    Reply
  31. nusya39

    А скажи как переделать эту обработку под БП 1.6??? Очень нужно..

    Reply
  32. wing

    А разве фраза

    Данный пример генерирует штрихкод к документу, справочнику с использованием стандартной компоненты 1CBARCOD.DLL, которая прилагается к обработке.

    не должна подразумевать, что данная dll содержится в обработке или в архиве с обработкой?

    P.S.: Dll уже нашел, но описание некорректно…

    Reply
  33. qwqwqwqwqwqw

    Пригодилась…

    Reply
  34. serge_focus

    Понравилось. Рекомендую Как пример обработки для изучения стандартной компоненты ActiveX 1CBARCOD.DLL …

    Reply
  35. Sairys

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

    Reply
  36. Sairys

    Спасибо за обработку, могу сказать что данная обработка понадобилась как нельзя кстати. Спасибо разработчику за это.

    Reply
  37. jack_kkm

    От лица своей лени выражаю автору благодарность 🙂

    Спасибо, пригодился код.

    Reply
  38. zaxarovsky

    Вопрос автору:

    подскажите пжлст, как быть с таким кодом 10435629912040100206299000081001002227 ?

    При раскодировании зацикливается на функции КонтролСумма

    пришлось поставить такое условие в конце, чтобы база не висела хотябы

    Если УбратьЗн = ДлКода Тогда
    Сообщить(«Внимание! Ошибка распознавания штрихкода!», СтатусСообщения.Важное);
    прервать;
    КонецЕсли;
    

    сам штрихкод — к такому документу: Лист комплектации 000081006 от 04.04.2012

    префикс типа документа использую «С»

    Reply
  39. aipnnov

    (38) haz,

    Этот код сформирован не правильно поэтому происходит зацикливание т.к. не возможно проверить контрольную сумму кода.

    Данная обработка выложена как пример генерации и расшифровки штрих-кодов (это не конечный продукт) поэтому могут быть ошибки или что-то не учтено при различных вариантах, но при этом генерация происходит корректно и соответственно расшифровка дает требуемый результат. Генерация происходит по международным правилам. Используется только латинский шрифт.

    Reply
  40. zaxarovsky

    (39)

    а где же неправильность?

    Reply
  41. aipnnov

    Вы с генерируйте штрих код через эту обработку, но в ней найдите и замените префикс определения документов, это можно сделать в модуле КнопкаВыполнитьНажатие(Кнопка) формы т.е. введите еще один тип документа:

    Если ТипЗнч(Документ) = Тип(«ДокументСсылка.РеализацияТоваровУслуг») Тогда
    СтрокаКод = Формат(Документ.Дата,»ДФ=yyMMdd»);
    СтрокаКод = «Р » + СтрокаКод + » » + ФорматКода(СокрЛП(Документ.Номер),УбратьЛидНули);
    ИначеЕсли ТипЗнч(Документ) = Тип(«ДокументСсылка.ПоступлениеТоваровУслуг») Тогда
    СтрокаКод = Формат(Документ.Дата,»ДФ=yyMMdd»);
    СтрокаКод = «П » + СтрокаКод + » » + ФорматКода(СокрЛП(Документ.Номер),УбратьЛидНули);
    ИначеЕсли ТипЗнч(Документ) = Тип(«ДокументСсылка.ПеремещениеТоваров») Тогда
    СтрокаКод = Формат(Документ.Дата,»ДФ=yyMMdd»);
    СтрокаКод = «В » + СтрокаКод + » » + ФорматКода(СокрЛП(Документ.Номер),УбратьЛидНули);
    ИначеЕсли ТипЗнч(Документ) = Тип(«ДокументСсылка.КомплектацияНоменклатуры») Тогда
    СтрокаКод = Формат(Документ.Дата, «ДФ=yyMMdd»);
    СтрокаКод = «С » + СтрокаКод + » » + ФорматКода(СокрЛП(Документ.Номер),УбратьЛидНули);

    Показать

    и т.д. далее по коду…

    После этого генерируйте штрих-код.

    Я сейсас поверил в документе Реализация товаров и услуг БД000002488 от 12.04.2011 6:29:08 и получил код Code128: 1044062991104110018620438441820242416 или EAN128: (20)40(15)110412(10)$FL2488, которые великолепно расшифровываются и открывается сам документ, к сожалению у меня нет документов комплектации т.к. мы ее не используем.

    Reply
  42. 2vadmaster

    Почему Оптимально, БазаМодеС = 6 ?

    Reply
  43. beldieff

    У меня не декодирует.

                   Если ТипШК = ПланыВидовХарактеристик.ТипыШтрихкодов.Code128
    Или ТипШК = ПланыВидовХарактеристик.ТипыШтрихкодов.Code39 Тогда
    СпрНом = Справочники.Номенклатура.НайтиПоКоду(Сред(РасшСтрока,3,5));
    ИначеЕсли ТипШК = ПланыВидовХарактеристик.ТипыШтрихкодов.EAN128 Тогда
    СпрНом = Справочники.Номенклатура.НайтиПоКоду(Сред(РасшСтрока,1,5));
    ИначеЕсли ТипШК = ПланыВидовХарактеристик.ТипыШтрихкодов.EAN8 Тогда
    СпрНом = Справочники.Номенклатура.НайтиПоКоду(Сред(ШК,2,5));
    Иначе
    Предупреждение(«Это штрихкод » + ТипШК + «,который необходимо занести в базу
    |и присвоить номенклатуре!»);
    КонецЕсли;
    
    СпрНом.ПолучитьФорму(«ФормаЭлемента»).Открыть();

    Показать

    Каким образом можно найти элемент с 11-значным кодом по 5-значному?

    Reply
  44. vlanik

    Обработка со своими задачами справляется вполне, если не заставлять ее декодировать «бог знает что», то все работает на ура.

    Reply
  45. mixqn

    Объясните мне, а зачем нужен такой сложный алгоритм кодирования CODE 128? Почему нельзя просто представить в виде кода любой нужный набор цифр, например в формате NNNNNNNNNyyyyMMdd, где NNNNNNNNN — номер документа без буквенного префикса, а yyyyMMdd — его дата в формате yyyyMMdd.

    например, для варианта приведенного выше: Реализация товаров и услуг БД000002488 от 12.04.2011 6:29:08, получим код 00000248820110412, его прекрасно можно представить в виде ШК CODE 128, он замечательно считается и далее уже по коду найдем документ.

    не понимаю, зачем так усложнять?

    Reply
  46. rozer

    все ок но пока в номерах документов не появились ЛАТИНСКИЕ буквы ) Пришлось допилить

    Reply
  47. pss1985

    а code 39 генерируется с контрольным символом?

    Reply
  48. aipnnov

    (48) pss1985, Делал давно и уже точно не помню, но должно быть с контрольной суммой, см. нужно сам код. Это не полноценная обработка, а ПРИМЕР кодирования и раскодирования по международным правилам, просто я ее сделал под документы, но могут возникать ошибки в определенных случаях, поэтому нужно ее допиливать под свои конкретные нужды.

    Reply

Leave a Comment

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