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




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

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 не будет опубликован. Обязательные поля помечены *