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




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2026-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 не будет опубликован. Обязательные поля помечены *