Стандартные доработки. Штрихкодирование документов.




Принцип обмена данными из 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='\

55 Comments

  1. kingan

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

    Reply ↓
  2. milkers
    kingan пишет:

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

    Изменение даты в пределах переодичности нумератора документа (чаще всего это год) на поиск не влияют. Измение номера явление достаточно редкое. А уникальный идентификатор слишком большой.

    Reply ↓
  3. parcan

    EAN128 допускает наличие в штрих-коде символов кириллицы?

    Reply ↓
  4. milkers

    (3) Нет

    Reply ↓
  5. artbear

    Лично я юзаю штрихкод «УникальныйИД + сумма документа» для контроля печатной формы, чтобы сразу исключить поддельные печатные формы.

    Reply ↓
  6. milkers

    (6) Хочу напомнить, что хотя в EAN128 длина штрихкода не ограниченна, остается еще и задача размещения штрихкода на печатных формах. И здесь чем он короче, тем это проще.

    Reply ↓
  7. SergeyT2006

    У Вас наверное только одна организация? Ибо может оказаться, а окажется обязательно, что существуют в одном году несколько документов одного типа, с одним номером, точнее с одной цифровой частью. Либо у Вас префикс номеров — латиница! Но об этом ограничении у Вас нигде не сказано.

    Мне пришлось реализовывать механизм транслитерации для обхода этого ограничения.

    ЗЫ Вроде у 1С есть стандартная компонента «1С:Печать штрихкодов», зачем такие сложности с подключением? … или в 8.2 все иначе 😳

    Reply ↓
  8. yandextesting

    Из каких именно типовых конфигураций можно взять макеты КомпонентаПечатиШтрихкодов…? В УТ 11 — нет, в УПП 1.3 — нет, думал в библиотеке стандарных подсистем должны быть — тоже нет.

    Reply ↓
  9. SergeyT2006

    Можно взять на диске ИТС, на сайте 1С… Могу выслать на мыло.

    Reply ↓
  10. SergeyT2006

    Файл называется «1CBarCode.exe»

    Reply ↓
  11. yandextesting

    Нашел макеты не в общих макетах, а в макетах обработки печати ценников и этикеток;

    (11) — для 8.2 не покатит по-моему для тонкого и веб клиента

    Reply ↓
  12. vladsol
    Reply ↓
  13. milkers

    (9)(11)(12) Откройте конфигурацию «управление небольшой фирмой». Сделайте глобальный поиск «КомпонентаПечатиШтрихкодовWindows32» только по свойствам. Скопируйте через буфер обмена готовый макет (сначала встав на него в дереве конфигурации) и вставьте его в ветку «общие макеты» в своей конфигурации. Аналогично остальные макеты.

    Reply ↓
  14. ilp06

    Я делал двумя путями.

    Первый — перекодирование в бинарный формат уникального идентификатора, иначе картинка штрих-кода слишком длинная.

    Второй — специальная перекодировочная табличка (регистр сведений) — объект->код.

    Печать в обоих случаях без каких либо компонент шрифтом BarCode.

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

    Reply ↓
  15. Ткачев

    (0)>3. Модифицируем печатные формы документов следующим образом: Добавим на печатные формы требуемых документов изображение штрихкода как на рисунке с примером макета.

    Где взять изображение штрихкода ?

    Reply ↓
  16. mugambi

    (8) SergeyT2006, компонента 1С:Печать штрихкодов не работает в Тонком клиенте

    Reply ↓
  17. vbuots

    Помогите разобраться, кусок этого модуля скопировал 1:1. Только, есть одно отличие, модуль находится во внешней обработке.

    Ошибка:

    {ВнешняяОбработка.ххх.МодульОбъекта(296)}: Поле объекта недоступно для записи (Картинка)

    Рисунок.Картинка = Обработки.ПечатьЭтикетокИЦенников.ПолучитьКартинкуШтрихкода(ВнешняяКомпонента, ПараметрыШтрихкода);

    Скрин из отладчика:

    Reply ↓
  18. milkers

    (19) Почему Объект — ActiveX? Объект должен же быть просто картинкой.

    Reply ↓
  19. vbuots

    (20)

    Обработки.ПечатьЭтикетокИЦенников.ПолучитьКартинкуШтрихкода(ВнешняяКомпонента, ПараметрыШтрихкода); — тут возвращается картинка, вот кусок модуля «ПолучитьКартинкуШтрихкода»:

     // Сформируем картинку
    ДвоичныеДанныеКартинки = ВнешняяКомпонента.ПолучитьШтрихкод();
    
    // Если картинка сформировалась
    Если ДвоичныеДанныеКартинки <> Неопределено Тогда
    // Формируем из двоичных данных
    Возврат Новый Картинка(ДвоичныеДанныеКартинки);
    КонецЕсли;
    

    Показать

    вот из отладчика



    все хорошо, но почему «Рисунок.Картинка » — не доступен для записи?

    Reply ↓
  20. milkers

    (21) Внимательно посмотри тип объекта в шаблоне печатной форме. В режиме управляемых форм activex объекты не используются. Удали объект из шаблона и вставь, как в стандартной конфигурации, просто рисунок. Картинка этого рисунка и создается в Рисунок.Картинка = Обработки.ПечатьЭтикетокИЦенников.ПолучитьКартинкуШтрихкода(ВнешняяКомпонента, ПараметрыШтрихкода);

    Reply ↓
  21. vbuots

    (22)

    Спасибо большое, я уже отчаялся, подставил обычную картинку, все заработало.

    Reply ↓
  22. msv23

    Рисунок.Картинка = ПолучитьКартинкуШтрихкода(ВнешняяКомпонента, 361, 50, ЗначениеШтрихкода, 3);

    Последний параметр тип штрихкода. 3 это тип Code39.

    Reply ↓
  23. pitbul

    А вазможно ли эту доработку реализовать в конфигурации УТ 10.3…

    Reply ↓
  24. milkers

    (25). Да.

    Reply ↓
  25. Apostol_Andrey

    при печати документа штрихкод есть, а на предварительном просмотре нет

    в чем может быть проблема

    Reply ↓
  26. Arutunov

    Конф УТ 10.3 Подскажите пожалуйста не сориентируюсь, как добавить в Общий журнал документов, обработку внешнего события, что-бы начать обрабатывать сигнал от сканера для поиска документа?

    Reply ↓
  27. milkers

    (28) Arutunov, Скопируйте соответствующий код из любого документа или справочника. Например справочник номенклатура.

    Reply ↓
  28. Arutunov

    (29)Я правильно понимаю, нужно скопировать процедуру

    Процедура ВнешнееСобытие(Источник, Событие, Данные)

    ПолучитьСерверТО().ОбработатьВнешнееСобытие(Источник, Событие, Данные, );

    КонецПроцедуры // ВнешнееСобытие()

    Или ещё что-то? И вставить в модуль формы Документа контрагентов или куда?

    Reply ↓
  29. ratinc

    (29) Внешнее событие по какойто причине не срабатывает у журнала документов.

    К форме привязано, в любых формах кроме журналов срабатывает.

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

    Reply ↓
  30. Arutunov

    (31)Я тоже про это говорю.

    Reply ↓
  31. milkers

    (31)(32) Вы не правы, посмотрите формы списка номенклатуры например. Если будет время посмотрю, но сегодня не успеваю.

    Reply ↓
  32. ratinc

    (33) Я ничего не утверждаю, посему не могу быть неправым. В моем посте содержится вопрос.

    По поводу формы списка номенклатуры могу сказать, что наш с товарищем Арутюновым вопрос касается другого объекта конфигурации.

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

    Reply ↓
  33. Arutunov

    (34)ratinc это мы с тобой тормозим, а не программа. Просто в свойствах формы журнала документов нужно прописать процедуру Внешнее событие и процедуру при открытии, и все пойдет.

    Reply ↓
  34. ratinc

    (35) Я конечно понимаю, что как всегда проблема в какой нибудь галочке.

    Но у меня в данный момент воз и не сдвинулся.

    Событие формы «Внешнее событие» привязано к одноименной процедуре. А что такого вы добавили в событие «При открытии»?

    Reply ↓
  35. Arutunov

    В Процедуру ПриОткрытии надо всего навсего добавить ПолучитьСерверТО().ПодключитьКлиента(ЭтаФорма);

    Reply ↓
  36. Arutunov

    А еще нужно добавить в модуль формы Функцию:

    Функция ПоддерживаетсяВидТО(Вид) Экспорт

    Результат = Ложь;

    Если Вид = Перечисления.ВидыТорговогоОборудования.СканерШтрихКода Тогда

    Результат = Истина;

    КонецЕсли;

    Возврат Результат;

    КонецФункции // ПоддерживаетсяВидТО()

    Reply ↓
  37. ratinc

    (38) Спасибо за совет.

    Реально не хватало

    Процедура ПриОткрытии()
    ПолучитьСерверТО().ПодключитьКлиента(ЭтаФорма);
    КонецПроцедуры
    

    Я ще вставлю свои пять копеек. Не заморачивайтесь с вариантом создания ШК с кодированием номеров документов. Используйте сразу GUID объекта. Шансов нарваться на кирилический символ в коде объекта очень много. Оно вам надо?

    Если вы сильно ограничены областью в которую необходимо выводить ШК, и 36 символов у вас не влезают, то лучше вынести в константы или регистр сведений ту часть гуида, которая повторяется в объектах принадлежащих к одному типу данных. Нужно только помнить, что если вы пересоздадите базу, эти значения изменятся.

    Reply ↓
  38. lesorubka

    Спасибо за код. все получилось! Вставляла в БП 2.0

    Правда, не понятно, почему, но для толстого клиента функции работают из общего модуля (добавила в РаботаСТорговымОборудованием), а для тонкого клиента почему-то они не видны — Предприятие даже не загружается — сразу выдает ошибку. Пришлось их вставить в модуль менеджера документа, откуда идет печать.

    Может я чего-то недопонимаю?

    Reply ↓
  39. Dach

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

    А вот как штрихкод попадает в доп. свойства документа и откуда он берется — об этом я, возможно тоже напишу статью.

    Reply ↓
  40. Dach
    Reply ↓
  41. markgenuine

    Как данный код подстроить под Code39? Как данный код Code39 уменьшить в длинну?

    Reply ↓
  42. lesenoklenok

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

    Reply ↓
  43. sweety-twetty

    Подскажите, пожалуйста, при попытке печати внешней печ. формы со штрих-кодом в управляемых формах, получаю ошибку «Значение не является значением объектного типа (Сообщение)» из строки

    ОбластьМакета.Рисунки.ШтрихКод.Объект.Сообщение = ВРег(СокрЛП(СсылкаНаОбъект[0].Ссылка.УникальныйИдентификатор()))

    В обычном приложении печ.форма формируется правильно(в об.приложении ОбластьМакета.Рисунки.ШтрихКод.Объект=ActiveX, а в управл.приложении ОбластьМакета.Рисунки.ШтрихКод.Объект=Null). Подскажите,в чем может быть проблема? Заранее спасибо

    Reply ↓
  44. odineskin2

    решение рабочее, но для более «мудреного» использования штрих-кодирования предлагаю попробовать наш модуль http://infostart.ru/public/527954/

    встраивание штрих-кодов идёт не через стандартный функционал, а через более функциональную библиотеку.

    Reply ↓
  45. Antimyslitel

    ВнешняяКомпонента = ИМЯОБЩЕГОМОДУЛЯ.ПодключитьВнешнююКомпонентуПечатиШтрихкода();

    Перед выводом макета области со штрихкодом:

    ИМЯОБЩЕГОМОДУЛЯ.ВывестиШтрихкодДокументаВОбластьМакета(ВнешняяКомпонента,ОбластьМакета,»PER»+СтрЗаменить(Формат(Шапка.Дата,»ДФ=dd.MM.yy»),».»,»»)+Шапка.Номер);

    Куда это вставлять можно более детально?

    Reply ↓
  46. Antimyslitel

    {Документ.РеализацияТоваровУслуг(43,38)}: Неопознанный оператор

    ПередВыводомМакетаОбластиСоШтрихкодом<<?>>: (Проверка: Толстый клиент (обычное приложение))

    Дает что неопознанный оператор

    Reply ↓
  47. Antimyslitel

    {Документ.РеализацияТоваровУслуг(43,8)}: Неопознанный оператор

    Перед <<?>>Выводом Макета Области Со Штрихкодом: (Проверка: Толстый клиент (обычное приложение))

    Точнее так!

    Reply ↓
  48. EvgeniyNP

    Здравствуйте!

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

    В переменную «ЗначениеШтрихкода» я передаю строку ГУИДа документа.

    На макете картинка как у вас. Код не трогал.

    Что я делаю не так?

    UPD

    Изменил ТипКода на 4 (тип кода — CODE128), выводится ШК

    Reply ↓
  49. milkers

    (50) На картинке написано — неправильный штрихкод. Текущий формат штрихкода не может закодировать такую длинную последовательность.

    Reply ↓
  50. EvgeniyNP

    (51) сменил тип и вывелось.

    Еще вопрос, чтобы выводился текст под ШК, нужно проставить

    ВнешняяКомпонента.ОтображатьТекст = Истина;

    ?

    Reply ↓
  51. milkers

    (52) ОтображатьТекст (TextVisible) Булево + + Свойство указывает необходимость отображать текст штрихкода на его поверхности. Актуально только для тех типов штрихкодов, которые предусматривают вывод данной строки

    Reply ↓
  52. EvgeniyNP

    (53)Понял, спасибо.

    я так понимаю EAN8,EAN13,EAN128 могут это?

    Reply ↓
  53. МСН

    (8) компонента «1С:Печать штрихкодов» не работает для 64-разрядных и Линукс

    Reply ↓
  54. МСН
    Reply ↓
  55. Serg_1C(M)

    Типов печати штрихкодов много:

    // Параметры:

    // ТипКода число от 0 до 16

    // EAN8, EAN13, EAN128, Code39, Code128, Code16k, PDF417, Standart (Industrial) 2 of 5, Interleaved 2 of 5, Расширение Code39, Code93, ITF14, RSS14, CodaBar, EAN13 AddOn 2, EAN13 AddOn 5

    Нужно было посмотреть как оно работает и как выглядит (в частности мне нужен был PDF417)

    написал обработку для демонстрации возможностей всех типов штрихкодов (во вложении)

    так же можно посмотреть по ссылке

    My Webpage

    в конфигурации обязательно должен быть компонент ОбщийМакет.КомпонентаПечатиШтрихкодов (можно загрузить в свою конфу из указанной папки)

    Reply ↓

Leave a Comment

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